Son*_*ate 5 c# testing tdd unit-testing
我有以下方法,我正在寻找有效的单元测试,也给我很好的代码路径覆盖:
public TheResponse DoSomething(TheRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
BeginRequest(request);
try
{
var result = Service.DoTheWork(request.Data);
var response = Mapper.Map<TheResult, TheResponse>(result);
return response;
}
catch (Exception ex)
{
Logger.LogError("This method failed.", ex);
throw;
}
finally
{
EndRequest();
}
}
Run Code Online (Sandbox Code Playgroud)
该方法使用的Service和Logger对象被注入类构造函数(未显示).BeginRequest和EndRequest在基类(未示出)中实现.Mapper是用于对象到对象映射的AutoMapper类.
我的问题是为这样的方法编写单元测试的好的,有效的方法是什么,它还提供完整的(或有意义的)代码覆盖?
我是一对一测试主体的信徒,并且在VS-Test中使用Moq作为一个模拟框架(尽管我并没有因为这个问题而挂断了这个部分).虽然有些测试(例如确保传递null导致例外)很明显,但我发现自己想知道其他想到的是否有意义; 特别是当他们以不同的方式行使相同的代码时.
从您的帖子/评论来看,您似乎已经知道应该编写哪些测试,并且它与我在第一眼看到您的代码后测试的内容非常匹配。首先有一些明显的事情:
现在,困难的部分。根据您的基类是否是您可以访问的内容(例如,可以轻松更改它),您可以尝试称为Extract & Override的方法:
代码可能看起来或多或少像这样:
Base
{
protected virtual void BeginRequest(TheRequest request) { ... }
protected virtual void EndRequest() { ... }
}
Derived : Base // class you want to test
{
// your regular implementation goes here
// virtual methods remain the same
}
TestableDerived : Derived // class you'll actually test
{
// here you could for example expose some properties
// determining whether Begin/EndRequest were actually called,
// calls were made in correct order and so on - whatever makes
// it easier to verify later
protected override void BeginRequest(TheRequest request) { ... }
protected override void EndRequest() { ... }
}
Run Code Online (Sandbox Code Playgroud)
您可以在《单元测试的艺术》一书以及《有效处理遗留代码》中找到有关此技术的更多信息。尽管我相信可能有更优雅的解决方案,但这个解决方案应该使您能够测试流程并验证 DoSomething 方法内交互的一般正确性。
当您无权访问基类并且无法修改其代码时,当然会出现问题。不幸的是,我没有针对这种情况的“书外”解决方案,但也许您可以在 Derived 中围绕 Begin/EndRequest 创建虚拟包装器,并且仍然使用提取和覆盖 TestableDerived。
| 归档时间: |
|
| 查看次数: |
682 次 |
| 最近记录: |