-
Notifications
You must be signed in to change notification settings - Fork 59
Open
Description
Hi,
Related to #83, I'd like to share how I write Stealth's integration test. Source code can be found here https://github.com/josephktcheung/stealth-integration-test. @luizcarvalho @mgomes please take a look and see if this can be improved.
Steps:
-
Run
stealth newto generate a new stealth app -
Install following gems for testing
group :test do
gem "rack-test"
gem "rspec"
gem "mock_redis"
end- In
spec/spec_helper.rb
# coding: utf-8
# frozen_string_literal: true
require 'rspec'
require 'stealth'
require 'mock_redis'
require 'sidekiq/testing'
# Requires supporting files with custom matchers and macros, etc,
# in ./support/ and its subdirectories.
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'bot'))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'config'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
require_relative "../bot/helpers/bot_helper"
ENV['STEALTH_ENV'] = 'test'
RSpec.configure do |config|
I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..', 'config', 'locales', '*.{rb,yml}')]
config.include BotHelper
config.before(:each) do |example|
Sidekiq::Worker.clear_all
Sidekiq::Testing.fake!
$redis = MockRedis.new
allow(Redis).to receive(:new).and_return($redis)
end
config.filter_run_when_matching :focus
config.formatter = :documentation
config.before(:suite) do
Stealth.boot
end
end- Define
sample_messageclass inspec/support/sample_message.rb
class SampleMessage
def initialize(service:)
@service = service
@base_message = Stealth::ServiceMessage.new(service: @service)
@base_message.sender_id = sender_id
@base_message.timestamp = timestamp
@base_message
end
def message_with_text(message)
@base_message.message = message
self
end
def message_with_payload(payload)
@base_message.payload = payload
self
end
def message_with_location(location)
@base_message.location = location
self
end
def message_with_attachments(attachments)
@base_message.attachments = attachments
self
end
def sender_id
"8b3e0a3c-62f1-401e-8b0f-615c9d256b1f"
end
def timestamp
@base_message.timestamp || Time.now
end
def to_request_json
if @base_message.message.present?
JSON.generate({
entry: [
{
"messaging": [
"sender": {
"id": @base_message.sender_id
},
"recipient": {
"id": "<PAGE_ID>"
},
"timestamp": @base_message.timestamp.to_i * 1000,
"message": {
"mid":"mid.1457764197618:41d102a3e1ae206a38",
"text": @base_message.message
}
]
}
]
})
end
end
end- Define custom matcher
send_replyinspec/support/matchers/send_reply.rb(Thanks @sunny for correction)
RSpec::Matchers.define :receive_message do |message|
match do |client|
stub = double("client")
allow(stub).to receive(:transmit).and_return(true)
@replies.each do |reply|
expect(client).to receive(:new)
.with(hash_including(reply: hash_including(reply)))
.ordered
.and_return(stub)
end
json = message.to_request_json
post "/incoming/#{@service}", json, { "CONTENT_TYPE" => "application/json" }
end
chain :as_service do |service|
@service = service
end
chain :and_send_replies do |replies|
@replies = replies
end
end- In
spec/features/chatbot_flow_spec.rb
require "spec_helper"
describe "chatbot flow" do
include Rack::Test::Methods
def app
Stealth::Server
end
let(:message) {
SampleMessage.new(
service: "facebook"
)
}
let(:client) { Stealth::Services::Facebook::Client }
it "handles user conversation" do
Sidekiq::Testing.inline! do
expect(client).to receive_message(
message.message_with_text("hello")
)
.as_service("facebook")
.and_send_replies([
{
"recipient" => {
"id" => message.sender_id
},
"message" => {
"text" => "Hello World!"
}
},
{
"recipient" => {
"id" => message.sender_id
},
"message" => {
"text" => "Goodbye World!"
}
}
])
end
end
end- In
bot/controllers/hellos_controller.rb
class HellosController < BotController
def say_hello
send_replies
step_to flow: "goodbye"
end
end- Run
bundle e rspecand test passes
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels