如何测试实例的方法是否被调用?

问题描述 投票:0回答:1

假设我有以下代码:

class MyClass:
    def __init__(self, value=1):
        self.value = value
        self.destructive_stuff()

    def destructive_stuff(self):
        print("Running destructive commands on the host...")

    def compute_value(self):
        return self.value * 10

def main():
    sample = MyClass(value=5)
    print(f"Computed value: {sample.compute_value()}")

if __name__ == "__main__":
    main()

我想测试

main()
功能。具体来说,我想检查
compute_value()
方法是否已被调用。我正在使用模拟,因为我不想初始化
MyClass
的真实实例,因为它会运行
destructive_stuff()
:

import unittest
from unittest.mock import patch
import my_sample

class TestPieq(unittest.TestCase):
    @patch("my_sample.MyClass")
    def test_called(self, mock_myclass):
        my_sample.main()
        mock_myclass.compute_value.assert_called()

但是,当我运行它时,它失败了:

$ python3 -m unittest tests.py
Computed value: <MagicMock name='MyClass().compute_value()' id='140298914799936'>
F
======================================================================
FAIL: test_called (tests.TestSample)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.10/unittest/mock.py", line 1379, in patched
    return func(*newargs, **newkeywargs)
  File "/tmp/pieq/tests.py", line 9, in test_called
    mock_myclass.compute_value.assert_called()
  File "/usr/lib/python3.10/unittest/mock.py", line 898, in assert_called
    raise AssertionError(msg)
AssertionError: Expected 'compute_value' to have been called.

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (failures=1)

如果我直接在

patch
指令中定位该方法,我的测试会通过...但它使用真实的类,因此它调用
destructive_stuff()
方法!

class TestSample(unittest.TestCase):
    @patch("my_sample.MyClass.compute_value")
    def test_called(self, mock_myclass_compute):
        my_sample.main()
        mock_myclass_compute.assert_called()
$ python3 -m unittest tests.py
Running destructive commands on the host...
Computed value: <MagicMock name='compute_value()' id='140289139827584'>
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

如何实现我想要的?

python unit-testing testing mocking
1个回答
0
投票

由于它是您要测试的实例的方法,并且该实例是通过调用该类创建的,因此您应该在模拟类后面加上括号以获取用于测试的模拟实例:

mock_myclass().compute_value.assert_called()
© www.soinside.com 2019 - 2024. All rights reserved.