单元测试和模拟,如何重置它们?

Ber*_*nat 12 python python-unittest python-unittest.mock

我正在测试一个需要在构造函数中进行模拟的类,所以我通常这样做:

class TestActionManager(unittest.TestCase):
    @patch('actionlib.SimpleActionClient', return_value=create_autospec(actionlib.SimpleActionClient))
    def setUp(self, mock1):
        self.action_manager = ActionManager()
Run Code Online (Sandbox Code Playgroud)

然后在这个类中我添加了所有测试。所以第一个工作正常

    def test_1(self):
        self.action_manager.f()
        self.action_manager.f.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

但是如果我添加另一个测试并运行两者

    def test_2(self):
        self.action_manager.f()
        self.action_manager.f.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

它说 f 已被调用两次。我本来希望 setUp 在开始每个测试之前创建一个新的 ActionManager (从而创建一个新的模拟),但显然这没有发生,因为模拟以某种方式共享。我也尝试这样做

def tearDown(self):
    del self.action_manager
Run Code Online (Sandbox Code Playgroud)

但这并不能解决问题。

我读过 Python 测试中相关的内容 - 重置所有模拟? 解决方案是使用不同的库(我想避免的事情)

并以任何方式将模拟方法重置为其原始状态?- Python Mock - 模拟 1.0b1,它使用不同的类来执行此操作。

是否有可能在每次测试之前或之后重置同一类中的模拟?

pep*_*uan 22

我相信你正在寻找的是reset_mock

一般来说,它是如何工作的:

def test_1(self):
    f = MagicMock()  # or whatever you're mocking
    f()
    f.assert_called_once()
    f.reset_mock()
    f()
    f.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

结果将是PASSED

如果你想自动化,那么你将模拟的东西存储在 中setUp,并在其中tearDown调用模拟的东西的.reset_mock()方法。

def setUp(self, mock1):
    self.mock1 = mock1
    # ... do other things ...

def tearDown(self):
    self.mock1.reset_mock()
Run Code Online (Sandbox Code Playgroud)