模拟由静态方法调用的模块功能不起作用

时间:2019-03-28 11:20:16

标签: python python-3.x python-unittest python-unittest.mock

好的,我有一系列看起来像这样的Python3代码:


foo.py

from bar import ClassB

class ClassA:

    @staticmethod
    def get_all(fn):
        something = ClassB(fn)
        return something.lines()

bar.py

def baz(f):
    with open(f, 'rt') as fin:
        ln = fin.readlines()
    return ln

class ClassB:

    def __init__(self, f):
        self._baz = baz(f)

    def lines():
        return self._baz

现在,我编写这样的单元测试:

test_foo.py

from unittest import TestCase, mock
from foo import ClassA

class Test_A(TestCase):

    @mock.patch("bar.baz")
    def setUp(self, mock_baz):
        mock_baz.return_value = ['a', 'b']

    def test_1(self):
        self.assertEqual(ClassA.get_all('whatever'), ['a', 'b']

问题:

运行测试会导致FileNotFoundError,这意味着mock.patch("bar.baz")无法正常工作。

如何解决此问题,以便正确模拟baz()函数?

1 个答案:

答案 0 :(得分:1)

您的补丁程序似乎不适用于您的测试-您正在模拟的功能仅在setUp本身中被模拟。您可以尝试以下两种解决方案之一:

在setUp中手动创建补丁

class Test_A(TestCase):

    def setUp(self, mock_baz):
        mock_baz = mock.Mock(return_value=['a', 'b'])
        self.baz_patch = mock.patch("bar.baz", mock_baz)
        self.baz_patch.start()

    def tearDown(self):
        self.baz_patch.stop()
    ...

或者,仅在您的测试中对其进行模拟:

class Test_A(TestCase):

    @mock.patch("bar.baz")
    def test_1(self):
        mock_baz.return_value = ['a', 'b']
        self.assertEqual(ClassA.get_all('whatever'), ['a', 'b']