I work with python and I'm a bit new to testing. I often see tests replacing an external dependency with a local method like so:
import some_module def get_file_data(): return "here is the pretend file data" some_module.get_file_data = get_file_data # proceed to test
I see this referred to as "monkey patching" as in the question. I also see the word "mock" being used a lot alongside "monkey patching" or in what seem to be very similar scenarios.
Is there any difference between the two concepts?
Mock vs. So what is the difference between them? MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.
mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.
The term monkey patch seems to have come from an earlier term, guerrilla patch, which referred to changing code sneakily – and possibly incompatibly with other such patches – at runtime. The word guerrilla, nearly homophonous with gorilla, became monkey, possibly to make the patch sound less intimidating.
Monkey patching is reopening the existing classes or methods in class at runtime and changing the behavior, which should be used cautiously, or you should use it only when you really need to. As Python is a dynamic programming language, Classes are mutable so you can reopen them and modify or even replace them.
Monkey patching is replacing a function/method/class by another at runtime, for testing purpses, fixing a bug or otherwise changing behaviour.
The unittest.mock library makes use of monkey patching to replace part of your software under test by mock objects. It provides functionality for writing clever unittests, such as:
patch()
for the actual monkey patching.return_value
), raise specific exceptions (side_effect
).You can use mocking, for example, to replace network I/O (urllib, requests) in a client, so unittests work without depending on an external server.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With