python with assert_关于单元测试:在Python中模拟assert_called_with

我在理解以下代码未通过的原因时遇到了一些麻烦:

test.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)

bar.py

class Bar(object):

def add(self, x, y):

print('b.Bar --> Adding {} + {}'.format(x, y))

return x + y

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

Traceback(最近一次调用最后一次):

文件"/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site-packages/mock.py",第1201行,已修补

return func(* args,** keywargs)

在test_a_b中输入第12行的"test.py"

fake_Bar.add.assert_called_with(2,2)

在assert_called_with中输入文件"/Users/iain/PycharmProjects/testing/venv/lib/python2.7/site-packages/mock.py",第831行

引发AssertionError('预期调用:%s n不要调用'%(expected,))

AssertionError:预期调用:add(2,2)

不叫

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

编辑:由于Bar被Mock实例替换,Bar().add不知道它是一个方法(因此没有绑定任何东西)。 换句话说,Bar是Mock,Bar()是Mock,Bar().add也是Mock。 因此,bar.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)

我已经修改了测试,以便foo作为第一个arg传递给Bar.add.assert_called_with(),但测试仍然失败了吗? 输出读取相同(AssertionError:预期调用:add(,2,2)未调用)

哎呀,我的示例代码完全错了。 将以适当的答案更新一些。 抱歉!

谢谢! 我想我犯了错误,认为如果我嘲笑foo.Bar那么它的所有属性和方法都保持完整和不变,除非我明确地改变了他们的行为。 这可能是一个人可能会使用mock.patch.object方法吗?

patch.object和patch具有相同的功能; 他们只是使用不同的方式来引用要修补的对象。 要在foo模块中修补Bar,您将使用mock.patch(foo, 'Bar'),结果将是相同的。 不幸的是,我不知道有一种预先建立的方式来获得你想要的行为。

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

from bar import Bar

class Foo(object):

def add(self, x, y):

self.bar = Bar()

return self.bar.add(x, y)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值