Mimic Tutorial¶
There are a few core concepts to understand about how Mimic works. Essentially, there’s the part of the test where you setup your expectations, and then there’s the part where you put your mocks into replay mode and call your code like normal.
Warning
Be careful when stubbing out your dependencies, mimic enfoces the contract you setup with it. If you say something gets called and it doesn’t, mimic will raise an exception. You must provide a precise, deterministic view into what these Mock objects would do in regular service.
Note
The pymox project also has decent documentation.
Basics¶
Here’s a rundown of the stages of a mimic-based test:
- Mimic instance
- Mocking out objects
- Replaying the mock objects
- Verifying and Unsetting the stubs (or ending Replay mode)
Mimic Instance¶
One way or another, you need a mimic instance from which to issue your commands for which class, methods, or other structures need to be made into mock objects.
In many examples, you might see a situation like this:
from mimic import Mimic
mime = Mimic()
Often this will happen in a test classes setUp
method. However, you can save
yourself the trouble by having your test class inherit from mimic.MimicTestBase
:
When you do this, you get a self.mimic
instance for free. However, that’s
not the only reason to do so. The other advantage is that the “Unsetting stubs”
step will be done automatically at the end of each test method
(more on this later).
class MyTests(mimc.MimicTestBase):
def test_something(self):
self.mimic.stub_out_with_mock(...)
Mocking Out Objects¶
Mocking Out A Function Call¶
A vast majority of mocking can just be done by calling stub_out_with_mock
,
this is good for situations in which you just need to override a particular
function call so it doesn’t interact with an external system (database), and/or
you need to control the return values that the function returns.
# Now assuming that your test classes inherit from MimicTestBase
self.mimic.stub_out_with_mock(my_module, 'my_func')
my_module.my_func(mimic.ignore_arg()).and_return('Completed')
Mocking Out An Object¶
In situations where you need to access attributes and call functions on an object
my_module = self.mimic.create_mock_anything()
my_module.my_func(mimic.ignore_arg()).and_return('Completed')
Mocking Out A Class¶
In other situations you need to mock out the creation of an instance within the
code that’s being tested. In those cases use stub_out_class_with_mocks
.
Replaying Mock Objects¶
After setting expectations, we trigger replay mode
which means that we can
make our calls for testing now.
# Set expectations
self.mimic.replay_all()
# Call your code
# Make your assertions
self.assertTrue(my_func())
Unsetting Stubs/Verification¶
After all the mocks have played out (successfully hopefully!) we need to let Mimic know that it’s time to count all the calls and arguments that we setup in our expectations.
self.mimic.verify_all()
Note
This isn’t necessary if you’re inheriting from mimic.MimicTestBase
!
self.mimic.verify_all() will be called for you in that case!