相关问题可能就像这个one question。
我使用依赖注入作为我的应用程序的体系结构。然后我为它创建了单元测试。
注射架构可能是这样的:
IClassA(IClassB)
IClassB(IClassC1, IClassC2)
//more of it
请注意,此体系结构仅涉及服务对象,而不涉及存储库。现在我想知道,要测试什么课程。
如果我测试C1和C2类(最小的类),则不测试B类和A类。
如果我只测试A类(集成类),那么有太多的场景需要覆盖,而不是很多小模块。
如果我测试A类的模块,还测试C1和C2类,我认为这似乎是多余的。如果我想重构逻辑(在开发期间),我需要管理许多测试单元。
如果我用模拟类B测试A类,它将为每个类和模拟类创建几乎1:1。它不会造成太多嘲弄吗?
任何建议或想法都将受到赞赏。
编辑:
工作场景是指我想要提供文件信息(基于csv或xml),然后转换为实体。这个过程将是:
Classes的示例代码将是这样的(我跳过构造函数注入部分):
public class ClassA: IClassA{
public IEnumerable<Request> GetRequestFromFile(FileInfo info
, ref ValidationResult validationResult){
//read the file and get DataTable
iClassB.ConvertToRequest(dataTableResult, ref validationResult);
}
}
public class ClassB : IClassB{
public IEnumerable<Request> ConvertToRequest(DataTable dt
, ref ValidationResult validationResult){
foreach(DataRow row in dt.Rows){
// convert to flat request first, to avoid reading DataTable too much
iClassC1.Validate(rawRequest, ref validationResult);
iClassC2.Validate(rawRequest, ref validationResult);
}
if(validationResult.IsSuccess){
// convert and return the header-detail entity object
}
}
}
N.B:请忽略逻辑架构(例如:关于在验证期间不抛出异常等)
答案 0 :(得分:4)
你应该总是模仿所有外部影响,所以你只测试一件事和一件事的功能。它可能需要大量的模拟,但这并不是所有可用的模拟框架(例如Rhinomocks,Moq和许多其他)的问题。
遵循该规则,您应该始终:
IClassB
ClassA
IClass1
IClass2
和ClassB
如果你没有模拟注入的对象,那么在重构期间你会遇到令人困惑的测试失败。此外,您的测试将是集成测试而不是单元测试,因为它们取决于外部类的实现。
示例:您正在ClassA
中测试ClassATesFixture
。您决定使用生产代码IClassB
作为输入而不是模拟ClassB
。测试没问题。现在,您重构ClassB
,并引入错误。这将导致ClassATesFixture
中的测试失败,尽管ClassA中没有任何内容发生变化。
因此,如果在测试中使用真实对象作为intput,那么实际上测试的不仅仅是您设置的测试对象。最重要的是,你也会遇到令人困惑的testfailures。
理想情况下,除非测试类中的某些内容发生变化,否则测试不应该从绿色变为红色。模拟是实现这一目标的方法。
答案 1 :(得分:4)
我认为你误解了“单元测试”一词。单元测试意味着单独测试类。在您的情况下,您应该通过将假依赖项传递到类来进行测试。如果您在测试的类中不使用伪依赖项,则不会单独测试这些类,因此您不进行单元测试。在这种情况下你正在做的是集成测试。
所以你应该做的是对所有类进行单元测试,因为你正在练习依赖注入,所以很容易伪造出测试中的类依赖项。