测试模拟实例,同时保留其方法可执行
Test mocked instance while leaving its methods executable
我有一些类似于下面的代码,我想使用 pytest_mock
在 ClassToTest
中测试一些流程。为此,我需要向它传递一个实现某些特定方法的对象,在本例中为 method1
和 MockClass
中的 method2
。在使用 run()
执行 ClassToTest
实例后,我想检查 mock_class
中的某些方法是否被调用,而这些方法必须保持可执行。有什么方法可以做到这一点?
import ClassToTest
class MockClass:
def method1(self):
return "method1 output"
def method2(self):
return "method2 output"
def test_class_to_test():
mock_class = MockClass()
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
如果您只想模拟这些方法的输出,最简单的方法就是使用 MagicMock
并在那里进行修补:
def test_class_to_test(mocker):
mock_class = mocker.MagicMock()
mock_class.method1.return_value = "method1 output"
mock_class.method2.return_value = "method2 output"
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
(在这里使用 mocker
,因为你似乎使用 pytest-mock
)
这样你就不需要单独的 class 来模拟了。
您还可以将模拟移动到一个单独的夹具中:
@pytest.fixture
def mock_class(mocker):
mock_class = mocker.MagicMock()
mock_class.method1.return_value = "method1 output"
mock_class.method2.return_value = "method2 output"
yield mock_class
def test_class_to_test(mock_class):
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
如果您需要方法有参数,它会变得有点复杂 - 您可以使用 side_effect
和相应的函数来代替:
@pytest.fixture
def mock_class(mocker):
def method1(foo):
return "method1 output " + foo
def method2(foo):
return "method2 output " + foo
mock_class = mocker.MagicMock()
mock_class.method1.side_effect = method1
mock_class.method2.side_effect = method2
yield mock_class
我有一些类似于下面的代码,我想使用 pytest_mock
在 ClassToTest
中测试一些流程。为此,我需要向它传递一个实现某些特定方法的对象,在本例中为 method1
和 MockClass
中的 method2
。在使用 run()
执行 ClassToTest
实例后,我想检查 mock_class
中的某些方法是否被调用,而这些方法必须保持可执行。有什么方法可以做到这一点?
import ClassToTest
class MockClass:
def method1(self):
return "method1 output"
def method2(self):
return "method2 output"
def test_class_to_test():
mock_class = MockClass()
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
如果您只想模拟这些方法的输出,最简单的方法就是使用 MagicMock
并在那里进行修补:
def test_class_to_test(mocker):
mock_class = mocker.MagicMock()
mock_class.method1.return_value = "method1 output"
mock_class.method2.return_value = "method2 output"
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
(在这里使用 mocker
,因为你似乎使用 pytest-mock
)
这样你就不需要单独的 class 来模拟了。
您还可以将模拟移动到一个单独的夹具中:
@pytest.fixture
def mock_class(mocker):
mock_class = mocker.MagicMock()
mock_class.method1.return_value = "method1 output"
mock_class.method2.return_value = "method2 output"
yield mock_class
def test_class_to_test(mock_class):
class_to_test = ClassToTest(mock_class)
class_to_test.run()
mock_class.method1.assert_called()
mock_class.method2.assert_not_called()
如果您需要方法有参数,它会变得有点复杂 - 您可以使用 side_effect
和相应的函数来代替:
@pytest.fixture
def mock_class(mocker):
def method1(foo):
return "method1 output " + foo
def method2(foo):
return "method2 output " + foo
mock_class = mocker.MagicMock()
mock_class.method1.side_effect = method1
mock_class.method2.side_effect = method2
yield mock_class