There is no need to provide a separate constructor. Mocking patches your code to replace objects with mocks. Just use the mock.patch() decorator on your test methods; it'll pass in references to the generated mock objects.

Both producer.Producer() and consumer.Consumer() are then mocked out before you create the instance:

from unittest import mock


class MyTest(unittest.TestCase):
    @mock.patch('producer.Producer', autospec=True)
    @mock.patch('consumer.Consumer', autospec=True)
    def test_send_data(self, mock_consumer, mock_producer):
        # configure the consumer instance run method
        consumer_instance = mock_consumer.return_value
        consumer_instance.run.return_value = [
            {u'dataObjectID': u'test1'},
            {u'dataObjectID': u'test2'},
            {u'dataObjectID': u'test3'}]

        coor = MyCoordinator()
        # Create some data and send it to the producer
        for count in range(3):
            coor.sendData('test{}'.format(count) , None)

        # Now verify that the mocks have been called correctly
        mock_producer.assert_has_calls([
            mock.Call('test1', None),
            mock.Call('test2', None),
            mock.Call('test3', None)])

So the moment test_send_data is called, the mock.patch() code replaces the producer.Producer reference with a mock object. Your MyCoordinator class then uses those mock objects rather than the real code. calling producer.Producer() returns a new mock object (the same object that mock_producer.return_value references), etc.

I've made the assumption that producer and consumer are top-level module names. If they are not, provide the full import path. From the mock.patch() documentation:

target should be a string in the form 'package.module.ClassName'. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch() from. The target is imported when the decorated function is executed, not at decoration time.

Answer from Martijn Pieters on Stack Overflow
Top answer
1 of 1
54

There is no need to provide a separate constructor. Mocking patches your code to replace objects with mocks. Just use the mock.patch() decorator on your test methods; it'll pass in references to the generated mock objects.

Both producer.Producer() and consumer.Consumer() are then mocked out before you create the instance:

from unittest import mock


class MyTest(unittest.TestCase):
    @mock.patch('producer.Producer', autospec=True)
    @mock.patch('consumer.Consumer', autospec=True)
    def test_send_data(self, mock_consumer, mock_producer):
        # configure the consumer instance run method
        consumer_instance = mock_consumer.return_value
        consumer_instance.run.return_value = [
            {u'dataObjectID': u'test1'},
            {u'dataObjectID': u'test2'},
            {u'dataObjectID': u'test3'}]

        coor = MyCoordinator()
        # Create some data and send it to the producer
        for count in range(3):
            coor.sendData('test{}'.format(count) , None)

        # Now verify that the mocks have been called correctly
        mock_producer.assert_has_calls([
            mock.Call('test1', None),
            mock.Call('test2', None),
            mock.Call('test3', None)])

So the moment test_send_data is called, the mock.patch() code replaces the producer.Producer reference with a mock object. Your MyCoordinator class then uses those mock objects rather than the real code. calling producer.Producer() returns a new mock object (the same object that mock_producer.return_value references), etc.

I've made the assumption that producer and consumer are top-level module names. If they are not, provide the full import path. From the mock.patch() documentation:

target should be a string in the form 'package.module.ClassName'. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch() from. The target is imported when the decorated function is executed, not at decoration time.

🌐
SourceForge
python-mock.sourceforge.net
The Python Mock Module
It can mimic any other Python class, and then be examined to see what methods have been called and what the parameters to the call were. The constructor for the Mock class takes an optional dictionary specifying method names and values to return when that method is called.
🌐
Python
docs.python.org › 3 › library › unittest.mock-examples.html
unittest.mock — getting started
Instead, you can effectively wrap the date class with a mock, while passing through calls to the constructor to the real class (and returning real instances).
🌐
Python
docs.python.org › 3 › library › unittest.mock.html
unittest.mock — mock object library
A non-callable version of Mock. The constructor parameters have the same meaning of Mock, with the exception of return_value and side_effect which have no meaning on a non-callable mock.
🌐
Readthedocs
testslide.readthedocs.io › en › 1.3.0 › mock_constructor
mock_constructor() — TestSlide 1.3.0 documentation
mock_callable is a way to not only solve this for Python 3, but also provide the same interface for both. ... Patch the class at its module with a subclass of it, that is dynamically created. __new__ of this dynamic subclass is handled by mock_callable. mock_constructor comes out of the box with support for Python`s unittest (via testslide.TestCase) and TestSlide’s DSL.
🌐
Medium
medium.com › @george.shuklin › mocking-complicated-init-in-python-6ef9850dd202
Mocking complicated __init__ in Python | by George Shuklin | Medium
October 19, 2018 - class Compl(object): def __init__(self, arg1, arg2): self.var1 = complicated_to_mock(arg1) self.var2 = self.var2.complicated_to_mocK2(arg2) if self.var1 in self.var2 and self.var1 != self.var2: self.var3 = self.var2 - self.var1 + ctm3(ctm4()) def simple(self, arg3): if arg3 > self.var1: return None else: return arg3 - self.var1
🌐
Technical Feeder
technicalfeeder.com › 2023 › 08 › python-how-to-mock-constructor-with-mockito-for-unit-testing
Python How to mock constructor with mockito for unit testing | Technical Feeder
August 28, 2023 - From GE, we can access FolderGenerator constructor; thus it can be stubbed by when. Then, we can return the desired value by the combination of when and thenReturn. Check the following post if you are not familiar with mockito. ... mockito in Python doesn't have good documentation due to poor examples.
Find elsewhere
🌐
Snyk
fugue.co › blog › 2017-07-18-revisiting-unit-testing-and-mocking-in-python.html
Open Source & Cloud Native Application Security Blog | Snyk
July 7, 2018 - Level up your open source & cloud native application security knowledge. Stay up to date with news & happenings in cloud, container, serverless security & more!
🌐
Medium
medium.com › @saimun92 › learn-how-to-use-pytest-mock-to-mock-a-class-0cf2160eddc3
Learn how to use pytest-mock to mock a class! | by TechProGuide | Medium
October 25, 2023 - Make sure to replace your_module with the actual name of the module where SampleClass and MockClass are defined. In the code above, we use mocker.patch.object() to replace the constructor (__new__) of SampleClass with an instance of MockClass.
🌐
DEV Community
dev.to › chen_ashkenazi › mocking-python-classes-4h96
Mocking Python Classes - DEV Community
August 27, 2024 - Lately, I had to write unit tests using Pytest for a Python module. The module contains a class where other classes are initialize within its constructor. As usual I created a fixture for this class to make it easy to write a test for each class method. At this point I ran into some issues when I tried to mock the different classes initiated in the constructor.
🌐
The Dev World
sergiolema.dev › 2025 › 05 › 12 › python-unittest-mocking-constructors
Python Unittest Mocking Constructors - Sergio Lema
June 10, 2026 - The post discusses issues with mocking constructors in Python's unittest framework, suggesting that imports be structured differently to enable successful mocking. By importing the module instead of the class directly, the @patch decorator can function correctly, allowing for effective testing.
🌐
Hakin9
hakin9.org › what-the-mock - a-cheatsheet-for-mocking-in-python-by-yeray-diaz
404 - Hakin9 - IT Security Magazine
January 17, 2020 - eBooks · Courses · Subscription · Corporate · Education · About Us · Contact Us · No products in the cart · LOGIN / SIGN UP · Our brands
🌐
Toptal
toptal.com › python › an-introduction-to-mocking-in-python
Python Mocking: A Guide to Better Unit Tests | Toptal®
May 19, 2026 - Since the Python patch to sys is the outermost patch, it will be executed last, making it the last parameter in the actual test method arguments. Take note of this well and use a debugger when running your tests to make sure that the right parameters are being injected in the right order. Instead of mocking the specific instance method, we could instead just supply a mocked instance to UploadService with its constructor...
🌐
Readthedocs
testslide.readthedocs.io › en › main › patching › mock_constructor › index.html
mock_constructor() — TestSlide 2.7.1 documentation
Integration comes out of the box for TestSlide’s DSL: you can simply do self.mock_constructor() from inside examples or hooks.
Top answer
1 of 2
6

Since you're only interested in testing one method, why don't you just mock the entire HoldsData class and pin on it the x_coords method?

>>> mock = MagicMock(data={'points': [(0,1), (2,3), (4,5)]})
>>> mock.x_coords = HoldsData.__dict__['x_coords']
>>> mock.x_coords(mock)
[0, 2, 4]

This way you'll have full control over the x_coords input and output (either by side effect or return value).

Note: In py3k you could just do mock.x_coords = HoldsData.x_coords since there are no more unbound methods.

That could also be done in the constructor of the mock object:

MagicMock(data={'points': [(0,1), (2,3), (4,5)]}, x_coords=HoldsData.__dict__['x_coords'])
2 of 2
1

You're basically running into this issue due to this:

A test is not a unit test if:

  • It touches the filesystem

If you wish to follow this rule, you should modify the _parse method. In particular, it should not take a file as input. The task of _parse is to parse the data but where the data comes from is not the concern of that method.

You could have a string that contains the same data which is then passed to _parse. Similarly, the data could come from a database or somewhere else entirely. When _parse only takes the data as input, you can unit test that method in a much easier way.

It would look something like this:

class HoldsData(object):
    def __init__(self, path):
        self.data = {}
        file_data = self._read_data_from_file(path)
        self.data.update(self._parse(file_data))

    def _read_data_from_file(self, path):
        # read data from file
        return data

    def _parse(self, data):
        # do parsing

Clean code leads to clean tests of course. The best case would be to mock the data and to provide _parse with input and then test x_coords later. If that's not possible, I'd leave it as it is. If your six lines of mock code are the only part of the test cases that you're worried about, then you're fine.

Top answer
1 of 2
6

You have to patch the name, not the instance.

From the official Python documentation: Where to patch

patch() works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.

In your example, your class Foo is defined in a module foomod.py, so you have to patch foomod.Bar instead of mod.Bar.

You can put this into a fixture by using the mocker fixture from pytest-mock or with unittest.mock.patch.

@pytest.fixture # With pytest-mock
def mock_bar(mocker):
    return mocker.patch('foomod.Bar')

@pytest.fixture # With stdlib
def mock_bar():
    with patch('foomod.Bar') as mock:
        yield mock

# Usage
def test_foo(mock_bar):
    pass

To my knowledge, there is no significant difference between the two approaches. Both are cleaned up when the fixture goes out of scope.

2 of 2
1

I use the following to mock objects with pytest without the fixture decorator

# path.to.MyClass
class MyClass():
    def __init__(self, some_parameter: SomeObject) -> None:
        self.some_value = some_parameter

    def get_something(self) -> str:
        return 'Hello'


# tests.py
from pytest_mock.plugin import MockerFixture
from unittest.mock import MagicMock

def test_with_mock(mocker: MockerFixture) -> None:
    mock_myclass: MagicMock = mocker.patch('path.to.MyClass')

    mock_myclass_get_something: MagicMock = mocker.patch('path.to.MyClass.get_something')
    mock_myclass_get_something.return_value = 'World!'

    assert mock_myclass.get_something() == 'World!'
🌐
GitHub
github.com › python › cpython › issues › 95078
`unittest.mock.Mock` does not allow name attribute to be mocked in constructor · Issue #95078 · python/cpython
July 21, 2022 - Bug report Would like to set name attribute of a mocked object directly when creating Mock() object. Currently, the workaround is to do: from unittest.mock import Mock obj = Mock(x=1, y="val") obj.name = "name" instead of directly assign...
Author: python
🌐
Relaxdiego
relaxdiego.com › 2014 › 04 › mocking-objects-in-python.html
Mocking Objects in Python - relaxdiego
April 7, 2014 - Likewise, by using spec_set above, we are “freezing” the specs of the Mock object such that we don’t accidentally create phantom mock attributes or methods in it. That’s it for now. If you want to dive deeper into the internals of Python’s mocking library, head on over to the official documentation for unittest.mock.