我有一个在.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 Studio\2017\Professional\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Net.Http.dll
更精确)。
更新:如果我尝试调试到单元测试,则在我输入方法之前会发生错误。因此,虽然VS2017可以很好地编译测试,但是当测试运行器启动时,一切都会崩溃。对我来说听起来更像DLL地狱。
更新2 :如果我注释掉请求的设置,那么我可以调试到测试方法。如果我然后输入断点,然后使用立即窗口直接设置请求属性,它可以工作,并且没有方法未找到错误。我还禁用了Resharper并使用VS2017的测试资源管理器来运行测试,以防R#缓存某些内容,但它没有任何区别。
答案 0 :(得分:5)
看起来我的问题确实是DLL地狱,更具体地说是https://github.com/dotnet/corefx/issues/25773引用的DLL地狱。该问题是由包含对较新版本的System.Net.Http(4.2.0.0)的引用的其他NuGet包引起的。当前的解决方案似乎是将绑定重定向添加到降级程序集版本到预期版本(4.0.0.0),但到目前为止还没有帮助我。
对我有用的解决方案是安装最新的System.Net.Http NuGet包,并在我的测试项目中使用程序集绑定重定向,以确保它使用4.2.0.0版本而不是4.0.0.0。 / p>
答案 1 :(得分:0)
这通常是由针对.NET标准的nuget软件包的早期版本引起的,该版本依赖于OOB(“带外”)软件包。 OOB软件包是.dll框架(而非.NET标准)的dll的一种polyfill。 Here是对发生的事情的很好的解释。就我而言,以下帮助:
我确定了依赖于system.net.http 4.2.0 nuget软件包的nuget软件包,并升级了该软件包。
升级包中不再存在依赖项,因此我可以卸载system.net.http 4.2.0 nuget包。
升级后的程序包当然仍然需要引用system.net.http 4.0.0程序集,因此,如有疑问,您可以重新安装升级后的程序包以确保程序集引用位于您的*中。 .csproj文件。