6

I have a test file where I reuse the same mocks for each function.

@mock.patch.object(...)
def xyz(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....

@mock.patch.object(...)
def abc(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....

@mock.patch.object(...)
def lmn(mock_xyz):
    mock_xyz.side_effect = lambda x, y: None
    ....
.
.
.

How do I avoid defining the mocks each time? PS: I have only used one mock in the example but I have the same four mocks used in 6 test methods.

Keshav Malpani
  • 113
  • 1
  • 5
  • [This answer](https://stackoverflow.com/questions/57299968/python-how-to-reuse-a-mock-to-avoid-writing-mock-patch-multiple-times) explains how to do it in the `setUp` method of your test class. Slightly more detail than the existing answers below. – piedpiper May 25 '22 at 22:08

2 Answers2

0

You can define it in setUp() and make it a member of your TestCase class:

class MyTest(unittest.TestCase):
    def setUp(self):
        self.mock_xyz = mock.patch.object(...)
        self.mock_xyz.side_effect = lambda x, y: None

    def xyz(self):
        with self.mock_xyz:
            # Do test stuff
        ....
wholevinski
  • 3,658
  • 17
  • 23
  • If `mock_xyz` uses a session fixture from another file, how would I import and use it in `def xyz(self)` – Keshav Malpani Aug 02 '18 at 21:02
  • I don't understand your question. This answer solves your original question. If you'd like to add more to your question, please either: accept this one if it solves your problem and open a new question, or revise your original question to ask what you're really trying to solve. – wholevinski Aug 03 '18 at 11:27
0

I had this same issue, didn't really like the look of using one context manager per mocked object because 6+ nested with statements was getting a bit silly. Also, wasn't able to get that working on python 2.7 (even with unittest2), so not sure if it's a python 3 exclusive feature.

Anyway, figured I'd leave my solution here in case someone else comes looking like I did for a way to resolve this. I ended up with something like this:

import unittest2
from mock import patch

@patch('package.module.something')
@patch('package.module.SomeClass.something_else')
class TestBase(unittest2.TestCase):

    def setup_mocks(self, mock_object):
        mock_name = mock_object._mock_name
        if mock_name == 'something':
            # do something stuff
            mock_object.side_effect = lambda: 'something'
        elif mock_name == 'something_else':
            # do something else
            mock_object.side_effect = lambda: 'something else

    def test_stuff(self, *mocks):
        for m in mocks:
            self.setup_mocks(m)

        # do test stuff

Now I can add as many mocks as I want, and they get patched per test. Might run into an issue if there's two things with the same in different modules, but it hasn't happend yet, so I'll cross that bridge when I come to it ;)

Edward Spencer
  • 448
  • 8
  • 10