Python中的TDD:函数的依赖注入

时间:2017-11-02 18:10:28

标签: python unit-testing dependency-injection

我最近参加过TDD课程,并且我一直在努力将学习付诸实践。我一直致力于处理一些json文档的代码,这些文档涉及进行一些处理的函数,然后调用其他函数来完成部分工作。

因此,在一个类中,函数1调用函数2,然后继续调用函数3等。我一直在使用依赖注入来模拟函数2,因此我可以对函数1如何调用函数2进行断言。这涉及将mock作为参数传递给函数1,在单独开发函数时可以正常工作。但是,当我想运行真实的代码并将所有独立测试的函数串起来时,我遇到了问题。当我想要传递我的实际功能时,我似乎无法使它工作。下面的代码不起作用,但希望能够说明我想要做的事情。

class myclass:

   def function1(self, number, injected_function=function2):
        number = number + 1
        injected_function(number)

   def function2(self, number):
        number = number + 2
        print(number)

instantiated_class = myclass()
instantiated_class.function1(1)

通常情况下,我会这样做:

class myclass:

   def function1(self, number):
        number = number + 1
        self.function2(number)

   def function2(self, number):
        number = number + 2
        print(number)

instantiated_class = myclass()
instantiated_class.function1(1)

但显然这使得测试函数2的调用变得更加困难。我知道在这种情况下可以使用unittest.mock.patch,但这真的是所有这一切的解决方案吗?感觉就像我做了一些根本错误的事情 - 我是否认为这个TDD的方法有问题了??

1 个答案:

答案 0 :(得分:0)

如果您在问题中添加了您正在获得的错误,将会很有帮助。

使用Python 3.5运行代码,它为我提供了NameError: name 'function2' is not defined

问题在于function1定义时间function2尚未定义。在function1之前声明它将解决这个问题:

class myclass:

   def function2(self, number):
        number = number + 2
        print(number)

   def function1(self, number, injected_function=function2):
        number = number + 1
        injected_function(number)

这还没有解决所有问题。这里很棘手的是你直接引用function2而不是myclass,所以当你致电injected_function(number)时它不会被绑定到班级。这意味着参数self不会自动提供给它,因此function2将"参见"您以number传递的参数self然后它会抱怨它没有收到它的第二个参数number

您可以致电injected_function(self, number)来解决此问题,但这可能会带来更多麻烦。相反,你可以这样做:

class myclass:
   def function1(self, number, injected_function=None):
        if injected_function is None:
            injected_function = self.function2
        number = number + 1
        injected_function(number)

   def function2(self, number):
        number = number + 2
        print(number)

这样做会有效,因为您正在使用function2内的self引用。因此在定义时不需要它,参数self将绑定到方法调用。与此同时,您在提供不是方法的函数(不接受self参数的函数)方面遇到了问题。