简体   繁体   English

找不到WebApi控制器测试方法

[英]WebApi controller tests method not found

I have a very simple WebAPI 2 controller running on .NET Framework 4.6.2, that looks like this: 我有一个运行在.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);
    }
}

and am trying to write an NUnit test for it, like this: 并尝试为其编写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>();
    }
}

``` ```

However, when I run the test, I get the following error: 但是,当我运行测试时,出现以下错误:

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

The same code seems to work fine in similar projects based on .NET Framework 4.5.1, so I'm wondering if there's some sort of DLL hell going on here. 相同的代码在基于.NET Framework 4.5.1的类似项目中似乎可以正常工作,所以我想知道这里是否存在某种DLL地狱。 System.Web.Http is using Microsoft.AspNet.WebApi.Core.5.2.3 , whereas System.Net.Http is coming from the GAC (well, C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\MSBuild\\Microsoft\\Microsoft.NET.Build.Extensions\\net461\\lib\\System.Net.Http.dll to be more precise). System.Web.Http使用的是Microsoft.AspNet.WebApi.Core.5.2.3 ,而System.Net.Http则来自GAC(好吧, C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\MSBuild\\Microsoft\\Microsoft.NET.Build.Extensions\\net461\\lib\\System.Net.Http.dll进行更精确的描述)。

Update : if I try to debug into the unit test, the error occurs before I even enter the method. 更新 :如果我尝试调试单元测试,甚至在进入方法之前都会发生错误。 So although VS2017 compiles the tests just fine, when the test runner fires up, then everything falls apart. 因此,尽管VS2017可以很好地编译测试,但是当测试运行程序启动时,一切都会崩溃。 Sounds more like DLL hell to me. 在我看来,这听起来像是DLL的地狱。

Update 2 : if I comment out the setting of the request, then I can debug into the test method. 更新2 :如果我注释掉请求的设置,则可以调试到测试方法中。 If I then put in a breakpoint, and then use the Immediate window to directly set the request property, it works, and there is no Method not found error. 如果我随后将其置于断点中,然后使用“立即”窗口直接设置请求属性,则它可以正常工作,并且没有“找不到方法”错误。 I also disabled Resharper and used VS2017's Test Explorer to run the tests, in case R# was caching something, but it made no difference. 我还禁用了Resharper并使用VS2017的Test Explorer来运行测试,以防R#缓存某些内容,但这没什么区别。

It looks like my problem is indeed DLL hell, more specifically the DLL hell referenced by https://github.com/dotnet/corefx/issues/25773 . 看来我的问题确实是DLL地狱,更具体地说是https://github.com/dotnet/corefx/issues/25773引用的DLL地狱。 The issue is caused by other NuGet packages that contain references to the newer version of System.Net.Http (4.2.0.0). 此问题是由其他NuGet程序包引起的,这些程序包包含对System.Net.Http(4.2.0.0)的较新版本的引用。 The current solution appears to be to add a binding redirect to downgrade the assembly version to the expected version (4.0.0.0), but so far that has not helped me. 当前的解决方案似乎是添加绑定重定向,以程序集版本降级为预期的版本(4.0.0.0),但是到目前为止,这对我没有帮助。

The solution that did work for me was to install the latest NuGet package of System.Net.Http, and use assembly binding redirects in my test project to ensure that it used the 4.2.0.0 version instead of 4.0.0.0. 对我有用的解决方案是安装最新的System.Net.Http的NuGet程序包,并在我的测试项目中使用程序集绑定重定向,以确保它使用的是4.2.0.0版本而不是4.0.0.0版本。

This is often caused by early versions of nuget packages targeting .NET standard, which have dependencies on OOB ("out-of-band") packages. 这通常是由面向.NET标准的nuget软件包的早期版本引起的,该版本依赖于OOB(“带外”)软件包。 OOB packages are a kind of polyfill for dlls that are part of .NET framework but not .NET standard. OOB软件包是.dll框架(而非.NET标准)的dll的一种polyfill。 Here is a very good explanation of what happened. 是对发生的事情的很好的解释。 In my case, the following helped: 就我而言,以下帮助:

  • I identified the nuget package that had a dependency on the system.net.http 4.2.0 nuget package, and upgrade that package. 我确定了依赖于system.net.http 4.2.0 nuget软件包的nuget软件包,并升级了该软件包。

  • The dependency was no longer present in the upgraded package, so i could uninstall the system.net.http 4.2.0 nuget package. 升级包中不再存在该依赖项,因此我可以卸载system.net.http 4.2.0 nuget包。

  • The upgraded package of course still expects the reference to the system.net.http 4.0.0 assembly, so in case of doubt, you may reinstall the upgraded package to make sure that the assembly reference is in your *.csproj file. 当然,升级后的程序包仍然需要引用system.net.http 4.0.0程序集,因此,如有疑问,您可以重新安装升级后的程序包,以确保程序集引用位于* .csproj文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM