pmichna
pmichna

Reputation: 4888

Minitest::Mock#expect without specific order?

Suppose I have a class:

class Foo
  def process
    MyModel.where(id: [1,3,5,7]).each do |my_model|
      ExternalService.dispatch(my_modal.id)
    end
  end
end

I want to test it:

class FooTest < ActiveSupport::TestCase
  def process_test
    external_service_mock = MiniTest::Mock.new
    [1,3,5,7].each do |id|
      external_service_mock.expect(:call, true, id)
    end

    ExternalService.stub(:dispatch, events_mock) do
      Foo.new.process
    end
    external_service_mock.verify
  end
end

However, #expect enforces that the following calls are made in the same order as #expect was called. That's not good for me, because I have no confidence, in what order will the results be returned by the DB.

How can I solve this problem? Is there a way to expect calls without specific order?

Upvotes: 2

Views: 1091

Answers (1)

Jon M.
Jon M.

Reputation: 3548

Try Using a Set

require 'set'
xs = Set[3,5,7,9]

@cat = Minitest::Mock.new
@cat.expect :meow?, true, [xs]
@cat.meow? 7 # => ok...
@cat.expect :meow?, true, [xs]
@cat.meow? 4 # => boom!

Alternatively, a less specific option:

Given that the value returned by the mock isn't a function of the parameter value, perhaps you can just specify a class for the parameter when setting up your mock. Here's an example of a cat that expects meow? to be called four times with an arbitrary integer.

@cat = Minitest::Mock.new
4.times { @cat.expect(:meow?, true, [Integer]) }

# Yep, I can meow thrice.
@cat.meow? 3 # => true

# Mope, I can't meow a potato number of times.
@cat.meow? "potato" # => MockExpectationError

Upvotes: 2

Related Questions