单元测试MVC控制器致电呼叫静态库,调用外部API



美好的一天,

我对单元测试以下内容感到困惑:

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

库是执行某些工作单位的实现详细信息。应该完全抽象出来。如果您想运行集成测试,那是完全不同的测试样式。

最新更新