gui*_*ism 10 python testing unit-testing dependency-injection
一般来说,我希望禁用尽可能少的代码,我希望它是明确的:我不希望被测试的代码决定它是否是测试,我希望测试告诉代码"嘿,BTW ,我正在进行单元测试,你能否请你不要打电话给solr,相反,你可以把你要发送到solr的东西放在这个地方,这样我就可以检查它了.我有我的想法,但我不喜欢他们中的任何一个,我希望有一个很好的pythonic方式来做到这一点.
您可以使用Mock对象拦截您不想执行的方法调用.例如,您有一些类A,您不希望no()在测试期间调用方法.
class A:
def do(self):
print('do')
def no(self):
print('no')
Run Code Online (Sandbox Code Playgroud)
模拟对象可以继承A并覆盖no()以不执行任何操作.
class MockA(A):
def no(self):
pass
Run Code Online (Sandbox Code Playgroud)
然后,您将在测试代码中创建MockA对象而不是As.另一种做模拟的方法是拥有A并MockA实现一个通用接口InterfaceA.
有大量的模拟框架可供使用.请参阅StackOverflow:Python模拟框架.
特别要看:谷歌的Python模拟框架.
在单元测试中使用Michael Foord的模拟执行此操作:
from mock import Mock
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
def say(self, str):
print "%s says \"%s\"" % (self.name, str)
...
#In your unit test....
#create the class as normal
person = Person("Bob")
#now mock all of person's methods/attributes
person = Mock(spec=person)
#talkto is some function you are testing
talkTo(person)
#make sure the Person class's say method was called
self.assertTrue(person.say.called, "Person wasn't asked to talk")
#make sure the person said "Hello"
args = ("Hello")
keywargs = {}
self.assertEquals(person.say.call_args, (args, keywargs), "Person did not say hello")
Run Code Online (Sandbox Code Playgroud)