Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;依赖注入和单元测试问题_C++_Unit Testing_Dependency Injection - Fatal编程技术网

C++ C++;依赖注入和单元测试问题

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

假设我有一个BigClass类,它需要一个SmallClass类型的成员变量

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
是一个与单元测试无关的实现细节