我开始学习Python,与此同时,我尝试学习如何为我的代码编写测试。我决定使用 py.test 和 mock 。我给了一个相当大而复杂的类来编写测试,所以一开始我决定研究一个更简单的例子。
所以,我在一个名为person.py
的包中编写了一个非常简单的类(src_pkg
)
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def can_do_it(self, x):
result = True if x > 5 else False
print "result: ", result
return result
我想要做的是模拟Person类,并创建模拟类的实例,以便能够调用can_do_it()
方法。
我想这样做的原因,是因为我正在研究的真正的类,有一个非常复杂的构造函数,而且我不想通过写foo = Foo(x, y, z)
这样的东西来创建类的实例
所以,我已将测试代码(test_person.py
)写在一个名为test_pkg
的包中,该代码如下:
from mock import patch
class TestPerson():
def test_can_do_it(self):
with patch('src_pck.person.Person') as Person:
person = Person.return_value
print "can he do it? :", person.can_do_it(4)
但是当我跑步时:
$ py.test -v -s test_person.py
我得到以下结果:
platform linux2 -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- /home/kostas/.virtualenvs/excite/bin/python
collected 1 items
test_person.py:5: TestPerson.test_can_do_it Can he do it? : <MagicMock name='Person().can_do_it()' id='37709904'>
PASSED
我希望表达式print "can he do it? :", person.can_do_it(4)
会导致can he do it? : False
。因此,没有必要断言任何事情。
我认为当我运行测试时,它根本不会调用can_do_it()
方法! (否则会打印方法的打印声明,对吗?)
那么,我做错了什么?
任何帮助都会非常感激。
提前谢谢。
答案 0 :(得分:6)
使用__init__
修补mock.patch.object
方法:
from mock import patch
import src_pkg.person as p
class TestPerson():
def test_can_do_it(self):
with patch.object(p.Person, '__init__', lambda self: None):
person = p.Person()
print "can he do it? :", person.can_do_it(4)
答案 1 :(得分:1)
模拟对象有模拟方法,而不是真正的方法。真正的方法可能取决于具有正确类的真实的,完全构造的对象self
,模拟对象无法提供。如果您需要测试can_do_it
方法,则无法使用模拟Person
来执行此操作。
如果can_do_it
不依赖于具有完全构造的self
,则可以将实现移动到模块级函数或静态方法,并让实例方法调用:
class Person(object):
...
def can_do_it(self, x):
return _can_do_it(x)
def _can_do_it(x):
result = True if x > 5 else False
print "result: ", result
return result
然后你可以测试模块级功能。如果你需要Person
的某些部分,但是你不需要构造整个事物,那么你可以构造(或模拟)这些部分,并让模块级函数将它们视为参数。
如果can_do_it
取决于拥有真实self
或大部分真实Person
,您可能需要构建一个真实的{{1}}对象并调用该方法。