关于依赖注入和单元测试的C ++问题

时间:2011-04-07 14:45:19

标签: c++ unit-testing dependency-injection

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

class BigClass {
.....
private:
SmallClass obj;
};

我有两个问题:

1)我无法将SmallClass对象传递给BigClass的构造函数,因为BigClass需要处理一些文件(并获取一些数据)才能正确实例化SmallClass。我知道 进行依赖注入的正确方法是使用构造函数BigClass(SmallClass& obj)。如果SmallClass只能在BigClass之后实例化,我该如何解决这个问题呢? 住了一段时间?

2)这就是BigClass构建自身的方式:它遍历目录中的文件,读取一些文件以初始化其状态。如何使这个单元可测试?什么是从目录中读取文件以获取状态的构造函数的适当单元测试?

6 个答案:

答案 0 :(得分:1)

1)为了我,你必须为SmallClass引入一个工厂,并根据它为BigClass实例构建BigClass。

2)在我看来,在构造函数中使用它是一个坏主意,也许有一些显式方法会有所帮助(但需要更多才能正确回复)。

答案 1 :(得分:0)

打开

SmallClass obj;

SmallClass* obj;

然后,制作一个方法

setObj(SmallClass* _obj);

这样你就可以随时实例化它。您还可以注入一个模拟版本进行测试。

答案 2 :(得分:0)

1)只需在BigClass中创建一个函数,您可以随时传入SmallClass对象。它不必位于构造函数func(SmallClass* obj)

2)我会通过让你的程序生成一堆文件并将它们放入一个目录来对你的BigClass进行单元测试。然后在这些文件上运行bigClass,并根据BigClas提供的已知输出测试单个读取,以及您要测试的任何其他功能。完成后删除文件。

答案 3 :(得分:0)

您可以在SmallClass上进行两阶段初始化,即使用一个构造函数将其置于一个稳定但空的状态,然后使用init()函数转换SmallClass的空壳。 1}}成为一个工作和可用的对象。

这不是最优雅的解决方案(我个人不喜欢两阶段的初始化,因为你可以让周围的物体无法真正使用),但它可以在你的场景中使用。

另一种选择可能是在SmallClass *中使用BigClass并使用创建SmallClass对象的工厂并使用它来控制依赖注入。

答案 4 :(得分:0)

1)创建工厂,对于单元测试,更改创建对象的方法以创建模拟。

2)你可以创建另一个具有接口和派生的类,它是调用获取文件列表的包装器。然后,对于单元测试,您传递一个模拟对象。您可以将此类的对象传递给BigClass的构造函数,也可以使用工厂。

表示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();

答案 5 :(得分:0)

  

BigClass需要处理一些文件......以正确实例化SmallClass

我建议不要让构造函数执行I / O.考虑重新设计BigClass,以便在调用BigClass构造函数之外(之前)完成I / O,并将该I / O的结果传递给BigClass构造函数。

  

我知道进行依赖注入的正确方法

我断言(虽然有些人不同意我的观点),你不应该对仅作为实现细节出现的对象进行依赖注入。在这种情况下,如果BigClass没有getter方法返回SmallClass对象的副本或引用,则SmallClassBigClass的存在是一个实现细节,应与您的单元测试无关。

相关问题