Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python's mock.patch not patching class in unittest

Tags:

python

mocking

I'm getting confused by using Mock in my python unittests. I've made this simplified version of my problem:

I have this dummy class and methods:

# app/project.py

class MyClass(object):

    def method_a(self):
        print(FetcherA)
        results = FetcherA()

Which is using this class:

# app/fetch.py

class FetcherA(object):
    pass

And then this test:

# app/tests/test.py

from mock import patch
from django.test import TestCase
from ..project import MyClass

class MyTestCase(TestCase):

    @patch('app.fetch.FetcherA')
    def test_method_a(self, test_class):
        MyClass().method_a()
        test_class.assert_called_once_with()

I would expect that running this test would pass and that print statement, for debugging, would output something like <MagicMock name=...>. Instead it prints out <class 'app.fetch.FetcherA'> and I get:

AssertionError: Expected to be called once. Called 0 times.

Why isn't FetcherA being patched?

like image 809
Phil Gyford Avatar asked Aug 17 '15 17:08

Phil Gyford


People also ask

What is patch in Unittest Python?

patch() unittest. 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.

What is the difference between MagicMock and mock?

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.

Can you mock a class Python?

unittest.mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. unittest.mock provides a core Mock class removing the need to create a host of stubs throughout your test suite.

Can you use Unittest mock with Pytest?

mock.


Video Answer


1 Answers

OK, fourth time through I think I understood the 'Where to patch' section of the Mock docs.

So, instead of:

    @patch('app.fetch.FetcherA')

I should use:

    @patch('app.project.FetcherA')

Because we're testing the code in app.project.MyClass where FetcherA has been imported already. So at that point FetcherA is availably globally(?) within app.project.

like image 73
Phil Gyford Avatar answered Sep 30 '22 06:09

Phil Gyford