您可能会发现使用 MagicMocks 而不是补丁更容易做到这一点,这些方面的内容应该会有所帮助:
from mock import MagicMock
fake_foo_response = 'foo'
fake_bar_response = 'bar'
class FooTestCase(unittest.TestCase):
def setUp(self):
self.foo = Foo()
self.foo.get_foo = MagicMock(return_value=fake_foo_response)
self.foo.get_bar = MagicMock(return_value=fake_bar_response)
def test_get_foo(self):
response = self.foo.get_foo()
self.assertEqual(fake_foo_response, response)
def test_get_bar(self):
response = self.foo.get_bar()
self.assertEqual(fake_bar_response, response)
但是,我认为您需要查看您在示例中实际测试的内容。你在这里真正做的是:
- 创建
Foo
对象的实例。
- 修补函数以返回特定值。
- 调用修补函数(即不是真正的函数)并断言返回值。
您实际上根本没有测试该get_foo
功能,因此在您上面显示的状态下,此测试没有真正的价值。但是,您在此处展示的技术对于测试诸如 REST 客户端(它必须在被测单元之外调用外部服务)之类的东西非常有用。让我们假设您的实际get_foo
实现是这样的:
- 是否适用于输入参数
- 调用外部 URL 并获得响应(这是您要模拟的部分)
- 是否对响应起作用,并可能向调用者返回一些东西
如果对这个函数进行单元测试,你会想要编写一个测试来测试和测试上面第 1 点和第 3 点中的行为,但是get_foo
修补第 2 点。这是这种风格的修补变得非常有价值的地方,因为你可以使用它来测试get_foo
模拟单元外的呼叫,例如:
class Foo:
def get_foo(self, input):
url_param = <do something with input>
response = self._call_url(url_param)
output = <do something with response>
return output
class FooTestCase(unittest.TestCase):
def setUp(self):
self.foo = Foo()
self.foo._call_url = MagicMock(return_value='some response')
def test_get_foo(self):
output = self.foo.get_foo('bar')
self.assertEqual('ni', output)
现在,您可以使用补丁(通过MagicMock
来测试您get_foo
方法中的代码),而不必依赖调用单元外部的东西。
希望这可以帮助。