在Python中,在单元测试期间禁用某些代码的好方法是什么?

gui*_*ism 10 python testing unit-testing dependency-injection

一般来说,我希望禁用尽可能少的代码,我希望它是明确的:我不希望被测试的代码决定它是否是测试,我希望测试告诉代码"嘿,BTW ,我正在进行单元测试,你能否请你不要打电话给solr,相反,你可以把你要发送到solr的东西放在这个地方,这样我就可以检查它了.我有我的想法,但我不喜欢他们中的任何一个,我希望有一个很好的pythonic方式来做到这一点.

Pie*_*tte 7

您可以使用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.另一种做模拟的方法是拥有AMockA实现一个通用接口InterfaceA.

有大量的模拟框架可供使用.请参阅StackOverflow:Python模拟框架.

特别要看:谷歌的Python模拟框架.

  • 子类化实现模拟可能会带来您不需要的各种事物.此外,您的方法不会采用所需的第一个参数 (2认同)

man*_*est 5

在单元测试中使用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)