C++ C++;依赖注入和单元测试问题
假设我有一个BigClass类,它需要一个SmallClass类型的成员变量C++ C++;依赖注入和单元测试问题,c++,unit-testing,dependency-injection,C++,Unit Testing,Dependency Injection,假设我有一个BigClass类,它需要一个SmallClass类型的成员变量 class BigClass { ..... private: SmallClass obj; }; 我有两个问题: 1) 我无法将SmallClass对象传递给BigClass的构造函数,因为BigClass需要处理一些文件(并获取一些数据)来正确实例化SmallClass。我知道 进行依赖项注入的正确方法是使用构造函数BigClass(SmallClass&obj)。如果SmallClass只能在BigClass
class BigClass {
.....
private:
SmallClass obj;
};
我有两个问题:
1) 我无法将SmallClass对象传递给BigClass的构造函数,因为BigClass需要处理一些文件(并获取一些数据)来正确实例化SmallClass。我知道
进行依赖项注入的正确方法是使用构造函数BigClass(SmallClass&obj)
。如果SmallClass只能在BigClass完成后才能实例化,该如何解决这个问题
活了一段时间
2) BigClass就是这样构造自己的:它循环遍历目录中的文件,读取一些文件以初始化其状态。如何使此单元可测试?对于从目录中读取文件以获取状态的构造函数来说,什么是合适的单元测试
SmallClass obj;
进入
然后,制定一个方法
setObj(SmallClass* _obj);
这样,您可以随时实例化它。您还可以注入模拟版本进行测试。Turn
SmallClass obj;
进入
然后,制定一个方法
setObj(SmallClass* _obj);
这样,您可以随时实例化它。您还可以插入模拟版本进行测试。1)只需在BigClass中创建一个函数,您可以随时传入SmallClass对象。它不必位于构造函数func(SmallClass*obj)
2) 我会对你的BigClass进行单元测试,通过让你的程序生成一堆文件并将它们放入一个目录中来读取文件。然后在这些文件上运行bigClass,并根据BigClas假定提供的已知输出以及您想要测试的任何其他功能测试单个读取。完成后删除文件。1)只需在BigClass中创建一个函数,您可以随时传入SmallClass对象。它不必位于构造函数func(SmallClass*obj)
2) 我会对你的BigClass进行单元测试,通过让你的程序生成一堆文件并将它们放入一个目录中来读取文件。然后在这些文件上运行bigClass,并根据BigClas假定提供的已知输出以及您想要测试的任何其他功能测试单个读取。然后在完成后删除文件。您可以对
SmallClass
进行两阶段初始化,即使用一个构造函数使其进入稳定但为空的状态,然后使用一个init()
函数将SmallClass
的空外壳转换为工作且可用的对象
这不是最优雅的解决方案(我个人不喜欢两阶段初始化,因为你可以让一些不可用的对象四处浮动),但它可以在你的场景中工作
另一种选择可能是在
BigClass
中使用SmallClass*
,并使用创建SmallClass
对象的工厂来控制依赖项注入。您可以在SmallClass
上进行两阶段初始化,即使用一个构造函数将其放入稳定的,但是空状态,然后有一个init()
函数,该函数将SmallClass
的空外壳转换为一个工作且可用的对象
这不是最优雅的解决方案(我个人不喜欢两阶段初始化,因为你可以让一些不可用的对象四处浮动),但它可以在你的场景中工作
另一个选项可能是在BigClass
中使用SmallClass*
,并使用创建SmallClass
对象的工厂来控制依赖项注入。1)创建工厂,对于单元测试,将创建对象的方法改为创建模拟
2) 您可以创建另一个类,该类有一个接口和派生类,它是用于获取文件列表的调用的包装器。然后对于单元测试,传递一个模拟对象。您可以将此类的对象传递给BigClass的构造函数,也可以使用工厂
对于1),它是这样的(未测试):
1) 创建工厂,对于单元测试,将创建对象的方法改为创建模拟
2) 您可以创建另一个类,该类有一个接口和派生类,它是用于获取文件列表的调用的包装器。然后对于单元测试,传递一个模拟对象。您可以将此类的对象传递给BigClass的构造函数,也可以使用工厂
对于1),它是这样的(未测试):
1) 在我看来,您必须为SmallClass引入一个工厂,并让BigClass依赖它来构建SmallClass实例
2) 在我看来,在构造函数中包含这一点是一个坏主意,也许有一些显式方法会有所帮助(但需要更多的方法才能正确回答)。1)为了我,你必须为SmallClass引入一个工厂,让BigClass依赖它来构造SmallClass实例
2) 在我看来,在构造函数中使用这个方法是个坏主意,也许使用一些显式方法会有所帮助(但需要更多的方法才能正确回答)
BigClass
需要处理一些文件。。。正确实例化SmallClass
<>我建议不要让构造函数执行I/O。考虑重新设计<代码> BigClass <代码>,这样I/O在调用“代码> BigClass < /代码>构造函数的外部(之前)完成,I/O传递给<代码> BigClass < /Cult>构造函数。
我知道做依赖注入的正确方法
我断言(尽管有些人不同意我的观点)您不应该对仅作为实现细节出现的对象进行依赖性注入。在这种情况下,如果BigClass
没有返回SmallClass
对象副本或引用的getter方法,那么BigClass
中存在的SmallClass
是一个与单元测试无关的实现细节