Minitest - calling a mocked instance method from within another instance method


Minitest - calling a mocked instance method from within another instance method



I've come across some weird behavior in Minitest::Mock and can't figure out what's the reason behind it.


Minitest::Mock



Say I have this class A that has a method b that calls method c:


b


c


class A

def b
c
end

def c
1
end

end



I would like to mock the c method to return 2 instead of 1:


c


require 'minitest/autorun'

a = Minitest::Mock.new(A.new)
a.expect(:c, 2)



But for some reason b still returns 1:


b


> a.b
=> 1



Obviously calling c directly will work:


c


> a.c
=> 2
> a.c
MockExpectationError: No more expects available for :c:



Why is the expectation on c not being invoked when calling it from within the instance?


c




1 Answer
1



This is how Minitest::Mock works; the mock object is a wrapper around the "real" instance of A, and defined expectations intercept the method call before it ever gets to that instance. (Other methods, like b, with no expectations defined, are forwarded on unaffected -- though they do still pass through the mock.)


Minitest::Mock


A


b



When the instance makes method calls internally, they go directly to self, not back through the mock wrapper, so they're dispatched normally, with no chance for interception.


self





Thanks for the response @matthewd! So is there a way for me to stub c somehow? Say I'm trying to test a method of a Rails model which calls #save. I'd like to stub #save for performance reasons.
– Simon
Jul 1 at 12:49



c


#save


#save





You may want stub instead; mock's focus is on expectations, while stub is there to force behaviour into the system under test.
– matthewd
Jul 1 at 13:04


stub





But I do want to have expectations. My tested method might have some logic where it does or doesn't call the #save method and I want to fail the test accordingly.
– Simon
Jul 1 at 13:32





I don't know of a way to do that directly, sorry... the best option that comes to mind would be to stub the method with a mock, and that sounds a bit silly just saying it.
– matthewd
Jul 1 at 13:41






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API