【问题标题】:Python Mock - How to get the return of a MagicMock as if it was a normal methodPython Mock - 如何像普通方法一样获得 MagicMock 的返回
【发布时间】:2014-03-03 21:52:22
【问题描述】:

例如:

import mock

class MyClass(object):
    def foo(self, x, y, z):
        return (x, y, z)


class TestMyClass(TestCase)
    @mock.patch('MyClass')
    def TestMyClass(self, MyClassMock):
        foo_mock = MyClassMock.foo()

        self.assertEquals((x, y, z), foo_mock)

所以,真正的问题是:如何获得该测试的返回而不是获得此 <MagicMock name='MyClass.foo()' id='191728464'> 或如何处理此 MagicMock 对象以获取该测试的返回,该测试应该是一个包含 3 个元素且什么都没有的元组多还是少?

欢迎任何建议、任何想法、任何争论。 提前致谢!

【问题讨论】:

  • 您是否正在尝试测试MyClass.foo() 是否正常工作?因为那样你就不应该嘲笑它。
  • 没有。这个问题的想法是知道如何获得该测试的返回而不是 MagicMock 对象,因为我会在不同的场景中应用它。有些测试我需要确切的值作为回报,而不是 MagicMock 对象。
  • 我在下面构建了一个示例;一个确实模拟了其他东西,但确实设置了返回值。
  • 如果您真的想模拟 MyClass.foo(),那么您的示例过于冗长(而且不正确,def TestMyClass() 上没有 self)。在任何情况下,您都在直接调用模拟,并且原始的 MyClass.foo() 从不被调用,因为它已被模拟取代。
  • 不需要显式调用类,甚至不需要实例化它。模拟库使一切变得神奇。不知何故,按照我上面的示例代码,在运行测试后,foo_mock 将仅被称为<MagicMock name='MyClass.foo()' id='191728464'>

标签: python unit-testing mocking python-unittest python-mock


【解决方案1】:

如果您尝试测试 MyClass.foo() 是否正常工作,您应该不要模拟它。

Mocking 用于被测代码之外的任何东西;如果foo 调用了另一个外部函数some_module.bar(),那么你将模拟some_module.bar() 并给它一个分阶段的返回值:

import some_module

class MyClass(object):
    def foo(self, x, y, z):
        result = some_module.bar(x, y, z)
        return result[0] + 2, result[1] * 2, result[2] - 2

class TestMyClass(TestCase):
    @mock.patch('some_module.bar')
    def test_myclass(self, mocked_bar):
        mocked_bar.return_value = (10, 20, 30)

        mc = MyClass()

        # calling MyClass.foo returns a result based on bar()
        self.assertEquals(mc.foo('spam', 'ham', 'eggs'),
            (12, 40, 28))
        # some_class.bar() was called with the original arguments
        mocked_bar.assert_called_with('spam', 'ham', 'eggs')

在这里,我将mocked_bar.return_value 设置为调用模拟的some_module.bar() 函数时应返回的值。当被测代码实际调用bar() 时,mock 会返回该值。

当您不设置 return_value 时,将返回一个 new MagicMock() 对象,该对象将支持进一步调用,您可以像在 @ 上一样测试这些调用987654331@对象等

【讨论】:

  • 我会根据您的回答尝试一些事情。自愿的,我会反馈正在发生的事情。谢谢!
  • 这里到底在测试什么?您有一个模拟方法,您知道它返回什么。 MyClass.foo() 也将所有内容传递给 some_module.bar()。那么在什么情况下可能会失败呢?你在测试什么
  • @norbertpy,MyClass.foo 方法已经过单元测试。如果在MyClass.foo 方法中执行了一些错误操作,例如plus 操作与multiplication 错位,则此测试将失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多