1

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

4

1 回答 1

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. 是否对响应起作用,并可能向调用者返回一些东西

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

希望这可以帮助。

于 2014-07-09T09:01:38.327 回答