未找到 WebApi 控制器测试方法

WebApi controller tests method not found

我在 .NET Framework 4.6.2 上有一个非常简单的 WebAPI 2 控制器 运行,看起来像这样:

[RoutePrefix("Invitations")]
public class InvitationsController : CqrsApiController
{
    [HttpPost, Route("Clients/{id:long}/Actions/Cancel")]
    public IHttpActionResult PostClientInvitationCancel(long id, [FromBody] ClientInvitationCancelCommand command)
    {
        Execute(command);
        return SeeOther("Invitations/Clients/{0}", id);
    }
}

并且正在尝试为其编写 NUnit 测试,如下所示:

[TestFixture]
public class WhenExecutingAValidCommand
{
    [Test]
    public void ItShouldReturnARedirect()
    {
        var dispatcher = Substitute.For<ICqrsDispatcher>();
        var urlHelper = Substitute.For<UrlHelper>();
        urlHelper.Link(Arg.Any<string>(), Arg.Any<object>()).Returns("https://tempuri.org/");

        var sut = new InvitationsController(dispatcher);
        sut.Request = new HttpRequestMessage();
        sut.Configuration = new HttpConfiguration();
        sut.Url = urlHelper;

        var response = sut.PostClientInvitationCancel(1, new ClientInvitationCancelCommand());
        response.Should().BeOfType<SeeOtherRedirectResult>();
    }
}

```

但是,当我运行测试时,出现以下错误:

System.MissingMethodException : Method not found: 'Void System.Web.Http.ApiController.set_Request(System.Net.Http.HttpRequestMessage)'.
   at ApiProjectTests.InvitationsControllerTests.WhenExecutingAValidCommand.ItShouldReturnARedirect()

相同的代码似乎在基于 .NET Framework 4.5.1 的类似项目中运行良好,所以我想知道这里是否存在某种 DLL 问题。 System.Web.Http 使用 Microsoft.AspNet.WebApi.Core.5.2.3,而 System.Net.Http 来自 GAC(更准确地说,C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll)。

更新:如果我尝试调试到单元测试中,错误发生在我什至进入方法之前。因此,尽管 VS2017 可以很好地编译测试,但是当测试 运行ner 启动时,一切都会崩溃。对我来说听起来更像是 DLL 地狱。

更新2:如果我把请求的设置注释掉,就可以调试到测试方法中了。如果我然后打断点,然后使用 Immediate window 直接设置请求 属性,就可以了,而且不会出现 Method not found 错误.我还禁用了 Resharper 并使用 VS2017 的测试资源管理器来 运行 测试,以防 R# 正在缓存某些东西,但这没有任何区别。

看来我的问题确实是 DLL 地狱,更具体地说是 https://github.com/dotnet/corefx/issues/25773 引用的 DLL 地狱。该问题是由其他 NuGet 包引起的,这些包包含对更新版本 System.Net.Http (4.2.0.0) 的引用。当前的解决方案似乎是添加绑定重定向以将程序集版本降级到预期版本(4.0.0.0),但到目前为止这对我没有帮助。

对我有用的解决方案是安装 System.Net.Http 的最新 NuGet 包,并在我的测试项目中使用程序集绑定重定向以确保它使用 4.2.0.0 版本而不是 4.0.0.0 .

这通常是由针对 .NET 标准的早期版本的 nuget 包引起的,这些包依赖于 OOB ("out-of-band") 包。 OOB 包是一种用于 dll 的 polyfill,它是 .NET 框架的一部分,但不是 .NET 标准。 Here 很好地解释了发生的事情。就我而言,以下内容有所帮助:

  • 我确定了依赖于 system.net.http 4.2.0 nuget 包的 nuget 包,并升级了该包。

  • 升级包中不再存在依赖项,因此我可以卸载 system.net.http 4.2.0 nuget 包。

  • 升级包当然还是需要引用system.net.http4.0.0程序集,所以如有疑问,可以重新安装升级包,确保程序集引用在您的 *.csproj 文件中。