【问题标题】:mocking multiple response with mock in python在python中用mock模拟多个响应
【发布时间】:2014-07-08 20:06:19
【问题描述】:

我正在尝试为我使用 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/

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

【问题讨论】:

    标签: python unit-testing mocking python-mock


    【解决方案1】:

    您可能会发现使用 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. 是否对响应进行了一些处理并可能将某些内容返回给调用者

    如果对这个函数进行单元测试,你会想要编写一个测试来测试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 方法中的代码),而不必依赖调用单元外部的东西。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-03-10
      • 2022-06-23
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 2022-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多