Just to further explicate @panic's answer, let's assume you have a Book class:
require 'minitest/mock'
class Book; end
First, create a Book instance stub, and make it return your desired title (any number of times):
book_instance_stub = Minitest::Mock.new
def book_instance_stub.title
desired_title = 'War and Peace'
return_value = desired_title
return_value
end
Then, make the Book class instantiate your Book instance stub (only and always, within the following code block):
method_to_redefine = :new
return_value = book_instance_stub
Book.stub method_to_redefine, return_value do
...
Within this code block (only), the Book::new
method is stubbed. Let's try it:
...
some_book = Book.new
another_book = Book.new
puts some_book.title #=> "War and Peace"
end
Or, most tersely:
require 'minitest/mock'
class Book; end
instance = Minitest::Mock.new
def instance.title() 'War and Peace' end
Book.stub :new, instance do
book = Book.new
another_book = Book.new
puts book.title #=> "War and Peace"
end
Alternatively, you can install the Minitest extension gem minitest-stub_any_instance
. (Note: when using this approach, the Book#title
method must exist before you stub it.) Now, you can say more simply:
require 'minitest/stub_any_instance'
class Book; def title() end end
desired_title = 'War and Peace'
Book.stub_any_instance :title, desired_title do
book = Book.new
another_book = Book.new
puts book.title #=> "War and Peace"
end
If you want to verify that Book#title
is invoked a certain number of times, then do:
require 'minitest/mock'
class Book; end
book_instance_stub = Minitest::Mock.new
method = :title
desired_title = 'War and Peace'
return_value = desired_title
number_of_title_invocations = 2
number_of_title_invocations.times do
book_instance_stub.expect method, return_value
end
method_to_redefine = :new
return_value = book_instance_stub
Book.stub method_to_redefine, return_value do
some_book = Book.new
puts some_book.title #=> "War and Peace"
# And again:
puts some_book.title #=> "War and Peace"
end
book_instance_stub.verify
Thus, for any particular instance, invoking the stubbed method more times than specified raises MockExpectationError: No more expects available
.
Also, for any particular instance, having invoked the stubbed method fewer times than specified raises MockExpectationError: expected title()
, but only if you invoke #verify
on that instance at that point.