关于依赖注入和单元测试的c++问题
C++ question on dependency injection and unit tests
假设我有一个类BigClass,它需要一个SmallClass类型的成员变量
class BigClass {
.....
private:
SmallClass obj;
};
我有两个问题:
1)我不能将SmallClass对象传递给BigClass的构造函数,因为BigClass需要处理一些文件(并获取一些数据)来正确地实例化SmallClass。我知道做依赖注入的正确方法是有一个构造函数BigClass(SmallClass& obj)
。如果SmallClass只能在BigClass实例化之后才实例化,我该如何解决这个问题活了一段时间?
2)这就是BigClass构造自己的方式:它循环遍历目录中的文件,读取一些文件来初始化它的状态。我如何使这个单元可测试?对于从目录中读取文件以获取状态的构造函数来说,什么是合适的单元测试?
1)为了我,你必须为SmallClass引入一个工厂,并让BigClass依赖于它来构建SmallClass实例。
2)在我看来,在构造函数中有这个是一个坏主意,也许有一些显式的方法会有所帮助(但需要更多的正确回复)。
Turn
SmallClass obj;
到
SmallClass* obj;
然后创建一个方法
setObj(SmallClass* _obj);
这样你就可以在任何你需要的时候实例化它。您还可以注入一个模拟版用于测试。
1)只需在BigClass中创建一个函数,您可以随时将其传递给SmallClass对象。它不一定要在构造函数func(SmallClass* obj)
2)我会通过让你的程序生成一堆文件并将它们放入一个目录来对你的读取文件的BigClass进行单元测试。然后在这些文件上运行bigClass,并根据bigClass应该给出的已知输出,以及您想要测试的任何其他功能,测试每个读取。
您可以对SmallClass
进行两阶段初始化,即有一个构造函数使其进入稳定但空的状态,然后有一个init()
函数将SmallClass
的空壳变成一个工作和可用的对象。
这不是最优雅的解决方案(我个人不喜欢两阶段初始化,因为你可以有浮动的对象,不是真正可用的),但它会在你的场景工作。
另一种选择可能是在BigClass
中使用SmallClass *
,并使用一个工厂来创建SmallClass
对象,并使用它来控制依赖注入。
1)创建一个工厂,对于单元测试,将创建对象的方法更改为创建一个mock。
2)你可以创建另一个类,它有一个接口和派生,这是一个包装器调用获取文件列表。然后,对于单元测试,传递一个模拟对象。您可以将这个类的对象传递给BigClass的构造函数,或者使用工厂。
for 1),它是这样的(未测试):
struct Factory
{
static SmallClassIface* Create()
{
return ReallyCreate();
}
typedef SmallClassIface* (funcPtr*)();
static funcPtr creator;
static SmallClassIface* DefaultCreator()
{
return new SmallClass;
}
};
Factory::funcPtr Factory::creator = &Factory::DefaultCreator();
BigClass
需要处理一些文件…正确实例化SmallClass
我建议不要让构造函数执行I/O。考虑重新设计BigClass
,使I/O在调用BigClass
构造函数之前完成,并将该I/O的结果传递给BigClass
构造函数。
我知道做依赖注入的正确方法
我断言(尽管有些人不同意我的观点),不应该对仅作为实现细节存在的对象进行依赖注入。在这种情况下,如果BigClass
没有返回SmallClass
对象副本或引用的getter方法,那么BigClass
中SmallClass
的存在是一个实现细节,应该与单元测试无关。
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 用于交叉编译和CMake的预处理器宏的单元测试
- C++ 用于单元测试的模板模板
- 提升 1.64 单元测试编译失败
- 单元测试欧拉到四元数实现失败
- 运行 C++ 单元测试时LNK2005链接错误
- 禁用自动捕获 Googletest 单元测试中的C++异常
- 有没有办法在不使用 #ifdef 的情况下不编译发布版本中的单元测试函数体?
- 使用 Google Test 对自定义断言函数进行单元测试
- 如何将我的 CMake 项目配置为运行所有单元测试?
- 在Qt C++单元测试中动态加载QQuickWindow而不是QQuickWidget
- MS 本机单元测试 - 断言::线程失败不起作用
- 如何获取 CMake 单元测试的相对路径?
- QTimer 超时不会在单元测试中触发
- 如何在提升构建中设置环境变量以进行提升单元测试框架?
- 在 AtMega32a 上运行的C++的单元测试
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 如何用 c++ 编写单元测试?