尝试使用 UrlHelper 测试控制器

Pix*_*ord 6 c# unit-testing xunit asp.net-core-mvc-2.0

尝试创建URLHelper用于测试目的会抛出NullReferenceException.

例子:

[Fact]
public async void AuthenticateAsyncTest()
{
  // Arrange
  var controller = new Controller(serviceProvider)
  {
    Url = new UrlHelper(new ActionContext()) // Exception thrown
  };

  // Act
  var result = await controller.Authenticate() as ViewResult;

  // Assert
  Assert.NotNull(result);
}
Run Code Online (Sandbox Code Playgroud)

每次运行此测试时,抛出的异常Url = new UrlHelper(new ActionContext())是:

异常消息:

消息:System.NullReferenceException:未将对象引用设置为对象的实例。

异常.StackTrace:

UrlHelperBase.ctor(ActionContext actionContext) ControllerUnitTest.AuthenticateAsyncTest()

使用:

xUnit 2.4.1、Microsoft.NETCore.App 2.2.0、Microsoft.AspNetCore.Routing.Abstractions 2.2.0

重新创建异常:

  1. 创建一个空的 MVC core 2.2 解决方案
  2. 创建 xunit 测试项目
  3. 安装 NuGet Microsoft.AspNetCore.Mvc.Core 2.2.0
  4. 在测试中写入:var Url = new UrlHelper(new ActionContext());
  5. 运行测试

应该看起来像这样:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using Xunit;

namespace XUnitTestProject1
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {
            var Url = new UrlHelper(new ActionContext());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 是否存在错误,或者为什么这不起作用?
  2. 解决方法的文献或链接值得赞赏吗?

Nko*_*osi 5

根据异常消息引用的GitHub源代码,

protected UrlHelperBase(ActionContext actionContext)
{
    if (actionContext == null)
    {
        throw new ArgumentNullException(nameof(actionContext));
    }

    ActionContext = actionContext;
    AmbientValues = actionContext.RouteData.Values;
    _routeValueDictionary = new RouteValueDictionary();
}
Run Code Online (Sandbox Code Playgroud)

帮助程序正在尝试访问actionContext.RouteData.Values原始示例中未提供的内容。

提供测试完成所需的依赖项。

[Fact]
public async Task AuthenticateAsyncTest() {
    // Arrange
    var httpContext = new DefaultHttpContext();
    var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
    var controller = new Controller(serviceProvider) {
        Url = new UrlHelper(actionContext)
    };

    // Act
    var result = await controller.Authenticate() as ViewResult;

    // Assert
    Assert.NotNull(result);
}
Run Code Online (Sandbox Code Playgroud)

还要避免使用 async void 进行单元测试。Task代替使用。