n 层架构的单元测试

pal*_*hta 5 c# unit-testing stub visual-studio

我使用 3 层架构:控制器、业务和数据层。在我的数据层中,我通过传递连接字符串和其他必要的参数来调用 Sql Server 数据库。

我必须为控制器层和业务层编写单元测试。我想编写一个存根(假存储库),从中返回硬编码值/结果。当我为业务层编写测试时,逻辑应该调用这个存根而不是真正的数据库。

我该如何在业务层编写代码来实现这一点?

业务层:

public string GetValues(string xmlData)
{
    DataObject do = new DataObject ();
    string result = do.GetValues(xmlData);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

数据访问:

public static string GetValues(string xmlData)
{
    return SqlHelper.ExecuteScalar(
        ConfigurationManager.AppSettings["ConnectionString"].ToString(),     
        "DBO.usp_GetDetail",
        xmlData
    ).ToString();
}
Run Code Online (Sandbox Code Playgroud)

k.m*_*k.m 2

为了测试您的场景,您的代码必须是可测试的。如果它遵循坚实的原则,那么它很可能是这样。但让我们重点关注进行此类单元测试的基本要素:

  1. 您的业​​务层应该依赖于抽象(这在大多数情况下意味着接口)而不是具体的类。这样,在单元测试中,您可以为这些依赖项提供存根。
  2. 业务层的依​​赖项应通过依赖项注入(例如构造函数注入)提供,以便在单元测试中您可以轻松地向它们传递存根对象。

同样的原则应该适用于控制器 - 业务层交互。当您坚持这两条规则(本质上缩小到 SOLID 的依赖倒置原则)时,您的代码将比其他规则更具单元测试性(坚持 SOLID 原则总体上是个好主意)。

由于您可能最终会编写模拟/存根,因此我建议使用现有的模拟框架,例如MoqFakeItEasy

编辑- 如果代码紧密耦合,您的选择仅限于:

  • 重构(这是显而易见的,但对于遗留系统来说可能是不可能的/值得付出努力)
  • 使用付费工具,例如 TypeMock Isolator。Isolator 使用编译器 API 拦截方法调用,因此可以对静态方法、私有成员以及免费框架不允许的所有内容进行存根/模拟调用。
  • 使用微软鼹鼠。Moles 利用动态装配生成来生成假类型。这为您提供了类似隔离器的灵活性,但是是免费的。请注意,它的框架有点(额外的程序集、文件等)。