在python中使用mock模拟多个响应

时间:2014-07-08 20:06:19

标签: python unit-testing mocking python-mock

我正在尝试为使用mock

编写的Rest客户端编写单元测试

假设此课程为Foo,并且有两种方法.. get_foo()get_bar()

这是我的测试类

fake_foo_response= 'foo'
class FooTestCase(unittest.TestCase):
  def setUp(self):
    self.patcher = patch('foo', fake_foo_response)
    self.patcher.start()
    self.foo = Foo()

  def tearDown(self):
    self.patcher.stop()

  def test_get_foo(self):
    response = self.foo.get_foo()
    self.assertEqual(response,'foo')

我基本上使用本教程来到这里:http://seminar.io/2013/09/27/testing-your-rest-client-in-python/

但是现在,我想测试吧...我如何用这种方法测试吧? 感谢

1 个答案:

答案 0 :(得分:0)

你可能会发现使用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实现是这样的:

  1. 是否有一些使用输入参数
  2. 调用外部URL并获取响应(这是您要模拟的部分)
  3. 是否有人使用响应并可能将某些内容返回给调用者
  4. 如果单元测试此函数,您可能希望编写一个测试get_foo的测试并测试上面第1点和第3点中的行为,但补丁指向第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方法中的代码),而无需依赖于调用设备外部的内容。

    希望这有帮助。