Does python mock module work by dependency injection? - python

So, the main question is on the title. I'm trying to find out if it is correct to say that python mock module uses dependency injection pattern for mocking object calls.
I'm not familiar with DI pattern but from what I've read and what I saw with debugger in mock module underhood look like mock() uses DI.
Am I right and mock() is DI or I'm missing something about this pattern and mocking?

The mock module does not use dependency injection.
mock replaces some objects with customized ones.
For dependency injection to be used, there would have to be some top level process, which would search for functions to be called, detected arguments to pass to them, instantiate them and finally made the call.
mock only modifies the object and the call to this objects is done as usual - direct call to that object.
If you want to find example of dependency injection, check pytest and it's fixtures - they use it a lot and it is fun to use that.

I suppose you are primarily concerned with mocking out an object's attributes with unittest.mock.patch.
patch is a function which does little more than return an instance of the class unittest.mock._patch. _patch is a context manager, which monkeypatches an attribute upon __enter__ and unpatches it upon __exit__.

Related

Does Python's unittest have a global setUp for an entire TestSuite?

I'm a bit new to Python's unittest library and I'm currently looking at setting up my Flask server before running any of my integration tests. I know that the unittest.TestCase class allows you to use setUp() before every test cases in the class. I also know that the same class has another method called setUpClass() that runs only once for the entire class.
What I'm actually interested is trying to figure out how to do something similar like setUpClass(), but done on an entire unittest.TestSuite. However, I'm having no luck at it.
Sure, I could set up the server for every TestCase, but I would like to avoid doing this.
There is an answer on a separate question that suggests that by overriding unittest.TestResult's startTestRun(), you could have a set up function that covers the entire test suite. However, I've tried to passed in the custom TestResult object into unittest. TextTestRunner with no success.
So, how exactly can I do a set up for an entire test suite?
This is not well documented, but I recently needed to do this as well.
The docs mention that TestResult.startTestRun is "Called once before any tests are executed."
As you can see, in the implementation, the method doesn't do anything.
I tried subclassing TestResult and all kinds of things. I couldn't make any of that work, so I ended up monkey patching the class.
In the __init__.py of my test package, I did the following:
import unittest
OLD_TEST_RUN = unittest.result.TestResult.startTestRun
def startTestRun(self):
# whatever custom code you want to run exactly once before
# any of your tests runs goes here:
...
# just in case future versions do something in this method
# we'll call the existing method
OLD_TEST_RUN(self)
unittest.result.TestResult.startTestRun = startTestRun
There is also a stopTestRun method if you need to run cleanup code after all tests have run.
Note that this does not make a separate version of TestResult. The existing one is used by the unittest module as usual. The only thing we've done is surgically graft on our custom implementation of startTestRun

Override Django module class method

In my Django application I have a module installed via pip. I need to override some method located in site-packages/module/views.py. I assume, I need to import this module in my custom modules directory, and simply inherit class and override method.
What is the best approach? How can I do it correctly without writing code in site-packages directory?
What you are after is often referred to as monkey patching.
import some_module
def my_method(self):
pass
some_module.SomeClass.a_method = my_method
Be careful though depending on the nature of the method and library initialization it may be too late to patch the method. For example if a method that you would like to patch is invoked as the module is loaded you will never be able to patch it before it is called.
Try and patch the class in question as early as possible in your application startup

pytest setup_class() after fixture initialization

I am experimenting with pytest and got stuck with some unobvious behavior for me. I have session-scope fixture and use it like this:
#pytest.mark.usefixtures("myfixt")
class TestWithMyFixt(object):
#classmethod
def setup_class(cls):
...
And when I run test I see that setup_class() comes before fixture myfixt() call. What is the purpose behind such a behaviour? For me, it should be run after fixture initialization because it uses fixture. How can I use setup_class() after session fixture initialization?
Thanks in advance!
I found this question while looking for similar issue, and here is what I came up with.
You can create fixtures with different scope. Possible scopes are session, module, class and function.
Fixture can be defined as a method in the class.
Fixture can have autouse=True flag.
If we combine these, we will get this nice approach which doesn't use setup_class at all (in py.test, setup_class is considered an obsolete approach):
class TestWithMyFixt(object):
#pytest.fixture(autouse=True, scope='class')
def _prepare(self, myfixt):
...
With such implementation, _prepare will be started just once before first of tests within the class, and will be finalized after last test within the class.
At the time _prepare fixture is started, myfixt is already applied as a dependency of _prepare.
Looking at the code behind usefixtures it appears the fixtures are handled by FixtureManager [1] which works on a per instance level. By marking a class with usefixtures, it appears to denote to the test framework that each of the callables contained within the scope should use those fixtures, but it does not apply the fixtures at that point. Instead, it waits for the callable to be called at which point it checks all of the managers for any updates it should do (including the FixtureManager) and applies the pieces appropriately. I believe this means that for each test within your class, it will reapply the fixture so that each test starts from a common base point which would be better behavior than the contrary.
Thus, your setup_class is called because that's the earliest order of operations. It sounds like you should put your setup_class logic into your fixture which will cause it to be called at the time the fixture is implemented.
[1] - https://github.com/pytest-dev/pytest/blob/master/_pytest/python.py#L1628
I know is an old post but the answer is pretty simple, maybe it will be useful for others.
You have to call super(...).setUpClass method in current setUpClass.
setUpClass is called once before the test methods and perform all actions. when you call super(...).setUpClass it applies the fixtures.
Note 1: i made some small changes to the code to be prettier.
Note 2: this method should be called setUpClass, it is mandatory.
class TestWithMyFixt(APITestCase):
fixture = ["myfixt"]
#classmethod
def setUpClass(cls):
super(TestWithMyFixt, cls).setUpClass()
...
This is my opinion, but maybe the purpose of this behavior is let the developer to choose when he want to load the fixture.

Python Mock type only within module

I am using mock for testing in Python. I am trying to unit test a metaclass which overwrites the __new__ method and then calls type.__new__(cls) internally.
I don't want to actually call type.__new__, so I want to mock out type. Of course, I can't patch __builtin__.type because it breaks object construction within the test.
So, I really want to limit mocking type within the module under test. Is this possible?
Yes. You patch as close to where you're going to call your function as possible for just these sort of reasons. So, in your test case, only around the function (or whatever callable) you'll call that's under tests, you can patch type.
The documentation for patch has plenty of examples for doing this if you'd like to peruse them.
Cheers.

How to mock Pythonic way?

Mox mocking library allows you to be either specific or agnostic about the class you are mocking.
mock = mox.CreateMock(Foo) or
mock = mox.CreateMockAnything()
Mox documentation suggests to use the first way (basically check the type of the mock) wherever it is possible. Python as a dynamic language is type agnostic. The two approaches look inconsistent to me.
So, which approach to mocking is more Pythonic?
They are not the same. From the documentation:
Some classes do not provide public interfaces; for example, they might
use __getattribute__ to dynamically create their interface. For these
classes, you can use a MockAnything. It does not enforce any
interface, so any call your heart desires is valid. It works in the
same record-replay-verify paradigm. Don't use this unless you
absolutely have to! You can create a MockAnything with the
CreateMockAnything method of your Mox instance like so:
In contrast, when creating a mock using CreateMock(Foo), you get an exception when an unknown method is called.

Categories

Resources