问题描述
我使用 3 层架构:控制器、业务和数据层.在我的数据层中,我通过传递连接字符串和其他必要参数来调用 Sql Server 数据库.
I am using 3 tier architecture: Controller, Business, and Data Layer. In my Data Layer, I am making a call to an Sql Server Database by passing Connection String and other necessary parameters.
我必须为控制器层和业务层编写单元测试.我想编写一个存根(假存储库),从中返回硬编码的值/结果.当我为业务层编写测试时,逻辑应该调用这个存根而不是真正的数据库.
I have to write unit tests for the Controller layer and Business layer. I want to write a stub (fake repository) from which I would return the hard coded values/result. When I write a test for business layer, the logic should call this stub instead of the real database.
如何在业务层编写代码来实现这一点?
How can I write the code in the business layer to achieve this?
业务层:
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();
}
推荐答案
为了测试你的场景,你的代码必须是可测试的.如果它遵循 SOLID 原则,它很可能是.但让我们关注进行此类单元测试的必要条件:
In order to test you scenario, your code has to be testable. If it follows SOLID principles it most likely is. But let's focus on what is essential to do this kind of unit testing:
- 您的业务层应该依赖于抽象(这在大多数情况下意味着接口)而不是具体的类.这样,在单元测试中,您可以为这些依赖项提供存根.
- 应通过依赖注入(例如构造函数注入)提供业务层的依赖项,以便在单元测试中您可以轻松地将存根对象传递给它们.
同样的原则应该适用于控制器 - 业务层交互.当您坚持这两条规则时(基本上缩小到 SOLID 的依赖倒置原则),您的代码将比其他方式更易于单元测试(坚持 SOLID 原则总体上是个好主意).
Same principles should apply to Controller - Business Layer interaction. When you stick to those two rules (which essentially narrows to SOLID's dependency inversion principle), your code will be much more unit testable than otherwise (sticking to SOLID principles is overall good idea).
由于您最终可能会编写模拟/存根,我建议使用现有的模拟框架,例如 Moq 或 FakeItEasy.
Since you'll probably end up writing mocks/stubs, I suggest using existing mocking framework, like Moq or FakeItEasy.
编辑 - 如果代码紧密耦合,您的选择仅限于:
Edit - if code is that tighly coupled, your options are limited to:
- 重构(这是显而易见的,但对于遗留系统可能不可行/值得付出努力)
- 使用付费工具,例如 TypeMock Isolator.Isolator 使用编译器 API 来拦截方法调用,因此可以存根/模拟对静态方法、私有成员以及免费框架不允许的所有内容的调用.
- 使用 Microsoft Moles.Moles 使用动态程序集生成来生成假类型.这为您提供了类似隔离器的灵活性,但它是免费的.请注意,它是一个更重的框架(额外的程序集、文件等).
- refactoring (this is obvious, but with legacy system might not be possible/worth the effort)
- use paid tool, like TypeMock Isolator. Isolator uses compiler API to intercept method calls and as a result can stub/mock calls to static methods, private members and all the stuff that free frameworks don't let you.
- use Microsoft Moles. Moles generate fake types utilizing dynamic assembly generation. This gives you Isolator-like flexibility, but is free. Note that it's a bit heavier framework (extra assembiles, files etc).
这篇关于n 层架构的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!