How do I mock part of a python constructor just for testing?

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:

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.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)