对数据对象的依赖注入
Dependency injection on data objects
我开始为我的 (python) 应用程序编写测试,我发现依赖注入非常有用。我重构了很多代码,编写测试非常容易。但是有些 classes 很棘手。
我有 class Application
,它是包含 name
、type
等属性的数据结构。它也很少有返回以某种方式修改这些属性的方法。没问题,但是有一种方法 instances
(显然)以 Process
对象列表的形式返回应用程序的实例。
class Application(object):
...
def instances(self):
return Processes.all().filtered(lambda process: process.name() == self.name)
可以看到对Processes
class的依赖。我该怎么办?
我是这样实现的,因为当我从某个地方得到一个 Application
对象时,我可以简单地调用 a.instances()
,得到进程列表而不关心。
但是从测试的角度来说,我想说"hey application, don't search for real processes in the system, look in this mocked processes list"。
我想到的第一个可能的解决方案是
def instances(self, processes=None):
processes = processes if processes else Processes.all()
return processes.filtered(...)
但这有点意味着我的所有调用可能都指定了该参数。 a.instances(some_processes_list)
不如 a.instances()
漂亮,可能会让人困惑。你会认为它令人困惑吗?
请问您推荐什么方法或模式?
您可以将进程 class 作为 class 属性:
class Application(object):
process_class = Processes
...
def instances(self):
return self.process_class.all().filtered(lambda process: process.name() == self.name)
并为其分配一个模拟class(TestProcess)进行测试(当然,这个新的class应该实现方法'all'和return你的模拟列表).
这似乎是一种非常清晰自然的方式,不涉及修补或添加新方法
我开始为我的 (python) 应用程序编写测试,我发现依赖注入非常有用。我重构了很多代码,编写测试非常容易。但是有些 classes 很棘手。
我有 class Application
,它是包含 name
、type
等属性的数据结构。它也很少有返回以某种方式修改这些属性的方法。没问题,但是有一种方法 instances
(显然)以 Process
对象列表的形式返回应用程序的实例。
class Application(object):
...
def instances(self):
return Processes.all().filtered(lambda process: process.name() == self.name)
可以看到对Processes
class的依赖。我该怎么办?
我是这样实现的,因为当我从某个地方得到一个 Application
对象时,我可以简单地调用 a.instances()
,得到进程列表而不关心。
但是从测试的角度来说,我想说"hey application, don't search for real processes in the system, look in this mocked processes list"。
我想到的第一个可能的解决方案是
def instances(self, processes=None):
processes = processes if processes else Processes.all()
return processes.filtered(...)
但这有点意味着我的所有调用可能都指定了该参数。 a.instances(some_processes_list)
不如 a.instances()
漂亮,可能会让人困惑。你会认为它令人困惑吗?
请问您推荐什么方法或模式?
您可以将进程 class 作为 class 属性:
class Application(object):
process_class = Processes
...
def instances(self):
return self.process_class.all().filtered(lambda process: process.name() == self.name)
并为其分配一个模拟class(TestProcess)进行测试(当然,这个新的class应该实现方法'all'和return你的模拟列表).
这似乎是一种非常清晰自然的方式,不涉及修补或添加新方法