简体   繁体   中英

How do I reuse same mocks for multiple functions in testing

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.

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
        ....

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 ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM