美好的一天,
我对单元测试以下内容感到困惑:
1。MVC控制器:
[HttpGet]
public async Task<PartialViewResult> DoExternalCallsAsync()
{
var model = new MyModel();
await MyStaticLibrary.DoExternalWorkAsync(Server.MapPath("~\") + "WorkSource.txt", model);
return PartialView("_MyResults", model);
}
2。静态库:
public static async Task DoExternalWorkAsync(string sourcePath, MyModel model)
{
var externalCalls =
System.IO.File.ReadAllLines(sourcePath)
.Where(line => (!string.IsNullOrEmpty(line) && line.First() != '#'))
.Select(p => DoExternalCall(p, model));
await Task.WhenAll(externalCalls);
}
private static async Task DoExternalCall(string urlPath, MyModel model)
{
var result = await GetExternalApiResultAysnc(urlPath);
// some code here...
return;
}
基本上,控制器所做的就是调用外部API,该API可以做一些工作并返回结果或抛出错误。
没有外部API的接口或抽象类。
我该如何进行单位测试?N. B.我没有自由改变外部API的设计。
谢谢,
使用代码中的静态类或方法使该代码难以正确地进行单位测试。请参阅单位测试的静态"邪恶"是静态的"邪恶",如果是的,为什么RESMARARPER推荐它?,单位测试中的静态类/方法/属性,是否停止,何时在C#中使用静态类。
将静态API调用类包装到带有接口的实例类中:
public interface IMyLibrary
{
Task DoExternalWorkAsync();
}
public class MyStaticLibrary : IMyLibrary
{
public async Task DoExternalWorkAsync(string sourcePath, MyModel model)
{
return await MyStaticLibrary.DoExternalWorkAsync(sourcePath, model);
}
}
然后,您可以将实例注入控制器的构造函数。
因为在此控制器操作方法中唯一应该测试单位的东西:
- 代码是否使用适当的参数调用图书馆?
- 该方法是否返回适当的对象?
在测试过程中,您可以在控制器中注入模拟的IMyLibrary
并验证控制器是否正确调用模拟,并且可以验证结果是包含其应包含的任何内容的PartialViewResult
。
库是执行某些工作单位的实现详细信息。应该完全抽象出来。如果您想运行集成测试,那是完全不同的测试样式。