首页 > 解决方案 > 模拟静态方法调用的模块函数不起作用

问题描述

好的,所以我有一系列 Python3 代码,如下所示:


foo.py

from bar import ClassB

class ClassA:

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

酒吧.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()正确地模拟函数?

标签: pythonpython-3.xpython-unittestpython-unittest.mock

解决方案


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

在 setUp中手动创建补丁:

class Test_A(TestCase):

    def setUp(self):
        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):
        mock_baz.return_value = ['a', 'b']
        self.assertEqual(ClassA.get_all('whatever'), ['a', 'b']

推荐阅读