在Python中用Mocking assert_called_

2024-04-18 23:08:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我无法理解为什么以下代码不通过:

测试.py

import mock
import unittest

from foo import Foo


class TestFoo(unittest.TestCase):
    @mock.patch('foo.Bar')
    def test_foo_add(self, Bar):
        foo = Foo()
        foo.add(2, 2)
        Bar.add.assert_called_with(2, 2)


if __name__ == '__main__':
    unittest.main()

foo.py

from bar import Bar

class Foo(object):
    def add(self, x, y):
        bar = Bar()
        return bar.add(x, y)

巴.py

class Bar(object):
    def add(self, x, y):
        print('b.Bar --> Adding {} + {}'.format(x, y))
        return x + y

在代码中,Foo.add创建Bar的实例,并在调用时返回Bar.add的结果。为什么测试assert_called_with失败?我相信我是在正确的地方模拟Bar(我是在模拟foo.Bar,因为这是正在查找的名称空间,而不是bar.Bar)。

回溯(最近一次呼叫时间): 文件“/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site packages/mock.py”,第1201行,已修补 返回func(*args,**keywargs) 文件“test.py”,第12行,在test_a_b中 假酒吧。添加。断言用(2,2)调用了 文件“/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site packages/mock.py”,第831行,在assert中调用 raise AssertionError('预期调用%s\n未调用'%(预期,)) 断言错误:预期调用:add(2,2) 不打电话


Tags: 文件pytestimportselfaddfoodef
2条回答

我相信你的问题会这样解决的:

from bar import Bar

class Foo(object):
    def add(self, x, y):
        self.bar = Bar()
        return self.bar.add(x, y)

您在正确的地方模拟方法调用。但是,由于您是从实例调用该方法,因此它是绑定方法,因此除了所有其他参数外,还将实例作为第一个参数(参数self)接收。

编辑:由于Bar替换为Mock实例,因此Bar().add不知道它是一个方法(因此不绑定到任何东西)。换句话说,Bar是一个MockBar()是一个MockBar().add也是一个Mockbar.add因此是一个新创建的模拟,用参数(2, 2)调用。断言此调用的一种方法是:

@mock.patch('foo.Bar')
def test_foo_add(self, Bar):
    foo = Foo()
    foo.add(2, 2)
    Bar.return_value.add.assert_called_with(2, 2)

根据实际代码的外观,您可能希望模拟方法而不是类:

@mock.patch('foo.Bar.add')
def test_foo_add(self, bar_add):
    foo = Foo()
    foo.add(2, 2)
    bar_add.assert_called_with(2, 2)

相关问题 更多 >