2011-04-07 89 views
1

假设我有需要类型的成员变量小类C++依赖注入和单元问题测试

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

类大类我有2个问题:

1)I不能通过一个小类对象BigClass的构造函数,因为BigClass需要处理一些文件(并获取一些数据)以正确实例化SmallClass。我知道 做依赖注入的正确方法是有一个构造函数BigClass(SmallClass& obj)。如果只有在BigClass有 生活了一段时间才能实例化SmallClass,我该如何解决这个问题?

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

回答

0

打开

SmallClass obj; 

SmallClass* obj; 

然后,做一个方法

setObj(SmallClass* _obj); 

这样,只要你想,你可以实例化。您还可以注入一个模拟版本进行测试。

0

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

2)我会单元测试你的BigClass读取文件,让你的程序做一堆文件并把它们放到一个目录中。然后在这些文件上运行bigClass,并根据BigClas应该给出的已知输出以及您想要测试的任何其他功能来测试单个读取。然后在完成后删除文件。

0

你可以做SmallClass两阶段初始化,即有一个构造函数,得到它变成一个稳定,但空状态,然后有一个init()功能,轮流的SmallClass空壳到工作和可用的对象。

这不是最优雅的解决方案(我个人不喜欢两级initalisation你可以有浮动周围已没有真正可重用的对象),但它会在你的情况下工作。

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

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(); 
1

1)为了我,你就来介绍的小类一家工厂,其大类取决于它的小类情况下施工。

2)在我看来,在构造函数中这是一个坏主意,也许有一些明确的方法会有所帮助(但更多是需要正确回复)。

+0

+1使用工厂。工厂可以改为单元测试来创建一个模拟。 – 2011-04-07 16:44:24

0

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

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

我知道正确的方式做依赖注入

我断言(虽然有些人会同意我的看法),您不应为仅存的对象做depenedency注射实施细节。在这种情况下,如果BigClass没有getter方法返回SmallClass对象的副本或引用,则BigClass中的SmallClass的存在是与您的单元测试无关的实现细节。

+0

我知道需要让构造函数不接触文件系统。但是,那么真正的I/O是谁呢?另一个完成工作并将结果传递给BigClass的类? – user231536 2011-04-08 14:41:50

+0

是的,类似的东西。 – Raedwald 2011-04-08 15:37:02