7

例如:

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 个元素的元组,仅此而已?

任何建议,任何想法,任何争论都将受到欢迎。提前致谢!

4

1 回答 1

6

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

模拟用于被测代码之外的任何东西;如果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')

Here I set mocked_bar.return_value to what should be returned when the mocked some_module.bar() function is called. When the code-under-test actually calls bar(), the mock returns that value.

When you don't set a return_value a new MagicMock() object is returned instead, one that'll support further calls, and you can test for those calls just like on the mocked_bar object, etc.

于 2014-02-06T19:02:58.353 回答