n层架构的单元测试

5
我正在使用三层架构:控制器、业务和数据层。在我的数据层中,我通过传递连接字符串和其他必要的参数来调用Sql Server数据库。
我需要为控制器层和业务层编写单元测试。我想编写一个存根(虚拟仓库),从中返回硬编码值/结果。当我为业务层编写测试时,逻辑应该调用这个存根而不是真正的数据库。
如何在业务层编写代码来实现这一点?
业务层:
public string GetValues(string xmlData)
{
    DataObject do = new DataObject ();
    string result = do.GetValues(xmlData);
    return result;
}

数据访问:

public static string GetValues(string xmlData)
{
    return SqlHelper.ExecuteScalar(
        ConfigurationManager.AppSettings["ConnectionString"].ToString(),     
        "DBO.usp_GetDetail",
        xmlData
    ).ToString();
}
1个回答

2
为了测试您的场景,您的代码必须是可测试的。如果它遵循SOLID原则,那么很可能是可测试的。但让我们专注于做这种单元测试所必需的要素:
  1. 您的业务层应该依赖于抽象(通常意味着接口)而不是具体类。这样,在单元测试中,您可以为这些依赖项提供存根。
  2. 业务层的依赖关系应通过依赖注入(例如构造函数注入)提供,以便在单元测试中可以轻松地传递它们的存根对象。
同样的原则也应该适用于控制器 - 业务层交互。当您遵循这两个规则(本质上缩小到SOLID的依赖反转原则)时,您的代码将比其他情况下更易于单元测试(遵循SOLID原则总体上是一个好主意)。
由于您可能最终会编写模拟/存根,因此建议使用现有的模拟框架,如MoqFakeItEasy编辑 - 如果代码耦合度很高,那么你的选择有限:
  • 重构(这是显而易见的,但对于遗留系统可能不可行/不值得付出努力)
  • 使用付费工具,例如TypeMock Isolator。Isolator使用编译器API拦截方法调用,因此可以桩/mock静态方法、私有成员和所有免费框架不允许的内容。
  • 使用Microsoft Moles。Moles利用动态程序集生成来生成虚假类型。这为您提供了类似于Isolator的灵活性,但是是免费的。请注意,它是一个有点笨重的框架(额外的程序集、文件等)。

谢谢Jimmy, 现有代码的问题是,它紧密耦合。 编码是使用具体类而不是接口完成的。 - palak mehta
@palakmehta:我明白了。这让测试变得更加复杂,但并不是不可能的。你可能需要使用不同的工具。查看我的编辑。 - k.m
@k.m,所以回顾一下,你最终做了什么?你最终使用了像 TypeMock 这样的工具,还是使用了 Sprout 方法重构代码库? - Vin Shahrdar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接