Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

[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:

[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. 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).

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. Sounds more like DLL hell to me.

Update 2: if I comment out the setting of the request, then I can debug into the test method. 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.

like image 999
David Keaveny Avatar asked Feb 06 '18 22:02

David Keaveny


1 Answers

It looks like my problem is indeed DLL hell, more specifically the DLL hell referenced by https://github.com/dotnet/corefx/issues/25773. The issue is caused by other NuGet packages that contain references to the newer version of 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.

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.

like image 191
David Keaveny Avatar answered Sep 27 '22 21:09

David Keaveny