Mocker 0.10 is out, with a number of improvements!
While we’re talking about Mocker, here is another interesting use case, exploring a pretty unique feature it offers.
Suppose we want to test that a method hello() on an object will call self.show(“Hello world!”) at some point. Let’s say that the code we want to test is this:
class Greeting(object): def show(self, sentence): print sentence def hello(self): self.show("Hello world!")
This is the entire test method:
def test_hello(self): # Define expectation. mock = self.mocker.patch(Greeting) mock.show("Hello world!") self.mocker.replay() # Rock on! Greeting().hello()
This has helped me in practice a few times already, when testing some involved situations.
Note that you can also passthrough the call. In other words, the call may actually be made on the real method, and mocker will just assert that the call was really made, whatever the effect is.
One more important point: mocker ensures that the real method exists in the real object, and has a specification compatible with the call made. If it doesn’t, and assertion error is raised in the test with a nice error message.
UPDATE: The method for doing this is actually mocker.patch() rather than mocker.mock(), as documented. Apologies.
However, isnt your use case invalid from the point of method encapsulation in that we should only be concerned with the results of a method call not how that method goes about its work to produce the results. The caller should depend on the “how” a method works only what inputs are and what expected outputs should be.
Yes, and no.
For sure I’d recommend against doing it if there are better alternatives (in most cases there are).
But notice that there is a whole thread of testing which advice more than only checking input and output (see Mocks Aren’t Stubs). Also, in case of non-idempotent methods, input/output may not be enough.
With that in mind, Mocker offers the feature. It’s up to the developer to understand when it’s a good idea and when it’s not.