Within my test I want to stub a canned response for any instance of a class.
It might look like something like:
Book.stubs(:title).any_instance().returns("War and Peace")
Then whenever I call @book.title
it returns "War and Peace".
Is there a way to do this within MiniTest? If yes, can you give me an example code snippet?
Or do I need something like mocha?
MiniTest does support Mocks but Mocks are overkill for what I need.
Just to further explicate @panic's answer, let's assume you have a Book class:
First, create a Book instance stub, and make it return your desired title (any number of times):
Then, make the Book class instantiate your Book instance stub (only and always, within the following code block):
Within this code block (only), the Book::new method is stubbed. Let's try it:
Or, most tersely:
Alternatively, you can install the Minitest extension gem 'minitest-stub_any_instance'. (Note: using this approach, the Book#title method must exist before you stub it.) Now, you can say more simply:
If you want to verify that Book#title is invoked a certain number of times, then do:
Thus, for any particular instance, invoking the stubbed method more times than specified raises
MockExpectationError: No more expects available
.Also, for any particular instance, invoking the stubbed method fewer times than specified raises
MockExpectationError: expected title()
, but only if you invoke #verify afterward on that instance.You can always create a module in your test code, and use include or extend to monkey-patch classes or objects with it. eg (in book_test.rb)
Now you can use it in your tests
This allows you to put together more complex behaviours than a simple stub might allow