Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rspec mock sequences?
# preferred format:
in_sequence(:task_order) do
task_one.should_receive(:execute)
task_two.should_receive(:execute)
end
# or even:
sequence = sequence(:task_order)
task_one.should_receive(:execute).in_sequence(sequence)
task_two.should_receive(:execute).in_sequence(sequence)
@foca

This comment has been minimized.

Copy link

foca commented Jan 30, 2012

This used to work with blocks:

task_one.should_receive(:execute) do
  task_two.should_receive(:execute)
end

Though I haven't tried this since forever, so YMMV :)

@lukeredpath

This comment has been minimized.

Copy link
Owner Author

lukeredpath commented Jan 30, 2012

@foca hey, that worked, thanks. It's not pretty, but it will do the trick.

@dchelimsky

This comment has been minimized.

@lukeredpath

This comment has been minimized.

Copy link
Owner Author

lukeredpath commented Jan 30, 2012

@dchelimsky does that work across different objects/mocks or only within the scope of a single receiver?

@dchelimsky

This comment has been minimized.

Copy link

dchelimsky commented Jan 30, 2012

Recollection is it works across objects, but the docs and specs don't say or specify that. Give it a whirl and let me know and I'll update the docs to answer that question.

@floehopper

This comment has been minimized.

Copy link

floehopper commented Jan 30, 2012

I assume you can still use Mocha with RSpec? Get your lovely sequences here ;-)

@dchelimsky

This comment has been minimized.

Copy link

dchelimsky commented Jan 31, 2012

@floehopper - the docs only show a single receiver - do they work across objects?

@floehopper

This comment has been minimized.

Copy link

floehopper commented Jan 31, 2012

Yes. I believe they do work across objects :-

require "test/unit"
require "mocha"

class FooTest < Test::Unit::TestCase
  def test_foo
    sequence = sequence(:task_order)
    task_one = mock("task_one")
    task_two = mock("task_two")

    task_one.expects(:execute).in_sequence(sequence)
    task_two.expects(:execute).in_sequence(sequence)

    task_one.execute
    task_two.execute
  end
end

I've added issue floehopper/mocha#59 to improve the examples in the docs. Thanks.

@dchelimsky

This comment has been minimized.

Copy link

dchelimsky commented Jan 31, 2012

Just tried it with both rspec and mocha and both do a less than desirable job. rspec doesn't enforce order across objects (so only mocha satisfies @lukeredpath's issue right now), but it's messaging is clear when order is violated within one object:

Failures:

  1) something does something
     Failure/Error: a.bar
       Double received :bar out of order
     # ./example_spec.rb:10:in `block (2 levels) in <top (required)>'

Mocha does enforce order across objects, but its messaging is unclear. Here's the result of the example with the last two lines reversed, e.g.

    task_one.expects(:execute).in_sequence(sequence)
    task_two.expects(:execute).in_sequence(sequence)

    task_one.execute
    task_two.execute
unexpected invocation: #<Mock:task_two>.execute()
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:task_one>.execute(any_parameters); in sequence :task_order
- expected exactly once, not yet invoked: #<Mock:task_two>.execute(any_parameters); in sequence :task_order

Looks like we both have some work to do :)

rspec/rspec-mocks#101
https://github.com/floehopper/mocha/issues/60

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.