slack-ruby / slack-ruby-bot

The easiest way to write a Slack bot in Ruby.
MIT License
1.12k stars 187 forks source link

Testing is difficult when the response text can be ignored #209

Open cabello opened 5 years ago

cabello commented 5 years ago

Hi πŸ‘‹

I have a scenario where the bot answers with two messages and the test is asserting measurements are being taken.

In this specific scenario I do not care about the bot's response, I just want to send the bot a message and assert, given the setup is a bit complex for that I would like to reuse whatever was already written for respond_with_slack_message (singular or plural form).

Attempt 1

Use the plural form respond_with_slack_messages with anything:

it 'tracks analytics' do
  expect(Analytics).to receive(:measure).once
  expect(message: "#{SlackRubyBot.config.user} command", channel: 'channel').to respond_with_slack_messages(anything)
end

I get the following failure:

ArgumentError:
  respond_with_slack_messages expects an array of ordered responses

Attempt 2

Use the plural form respond_with_slack_messages with [anything, anything]:

it 'tracks analytics' do
  expect(Analytics).to receive(:measure).once
  expect(message: "#{SlackRubyBot.config.user} command", channel: 'channel').to respond_with_slack_messages([anything, anything])
end

I get the following failure:

Expected text: #<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x00007fa203a78990>, got {:channel=>"channel", :text=>"text", :thread_ts=>nil}
Expected text: #<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x00007fa203a78990>, got {:channel=>"channel", :text=>"text", :thread_ts=>nil}

Attempt 3

Use the singular form respond_with_slack_message with anything:

it 'tracks analytics' do
  expect(Analytics).to receive(:measure).once
  expect(message: "#{SlackRubyBot.config.user} command", channel: 'channel').to respond_with_slack_message(anything)
end

I get the following failure:

expected to receive message with text: #<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x00007fdf995ec650> once,
  received:[{:channel=>"channel", :text=>"text", :thread_ts=>nil}, {:channel=>"channel", :text=>"text", :thread_ts=>nil}]

For now I decided to extract a variable called expected_messages and I assert them multiple times, once for the real response, others for behaviour like the analytical measurements.

dblock commented 5 years ago

Attempt 2 and 3 are both feature requests and we should have that. Want to attempt a PR?

Generally I'd like .to respond_with_slack_message or .to respond_with_slack_messages to work without arguments as well. That could be a lower hanging fruit.

dblock commented 5 years ago

Implemented in https://github.com/slack-ruby/slack-ruby-bot/pull/216.