Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing Controller Actions in MVC4 with Kendo UI

I'm in the process of writing some unit tests for our controllers. We have the following simple controller.

public class ClientController : Controller
{

    [HttpPost]
    public ActionResult Create(Client client, [DataSourceRequest] DataSourceRequest request)
    {
        if (ModelState.IsValid)
        {
            clientRepo.InsertClient(client);
        }

        return Json(new[] {client}.ToDataSourceResult(request, ModelState));
    }
}

The unit test for this is as follows:

[Test]
public void Create()
{
        // Arrange
        clientController.ModelState.Clear();

        // Act
        JsonResult json = clientController.Create(this.clientDto, this.dataSourceRequest) as JsonResult;

        // Assert
        Assert.IsNotNull(json);

}

And the controller context is faked with the following code:

 public class FakeControllerContext : ControllerContext
    {
        HttpContextBase context = new FakeHttpContext();

        public override HttpContextBase HttpContext
        {
            get
            {
                return context;
            }
            set
            {
                context = value;
            }
        }

    }

    public class FakeHttpContext : HttpContextBase
    {
        public HttpRequestBase request = new FakeHttpRequest();
        public HttpResponseBase response = new FakeHttpResponse();

        public override HttpRequestBase Request
        {
            get { return request; }
        }

        public override HttpResponseBase Response
        {
            get { return response; }
        }
    }

    public class FakeHttpRequest : HttpRequestBase
    {

    }

    public class FakeHttpResponse : HttpResponseBase
    {

    }


}

The exception occurs when the Create controller action attempts to to call the ToDataSourceResult method.

System.EntryPointNotFoundException : Entry point was not found.

Debugging shows that the ModelState internal dictionary is empty in the unit test (and not when run in a standard context). If the ModelState is removed from the ToDataSourceResult method then the test passes successfully. Any help is much appreciated.

like image 779
Alex Avatar asked Jun 19 '13 10:06

Alex


1 Answers

A quick peak in JustDecompile reveals that Kendo.Web.Mvc.dll was built against System.Web.Mvc version 3.0. Your test project probably references the newer version ASP.NET MVC (4.0) and so at runtime any calls into System.Web.Mvc members result in a System.EntryPointNotFoundException because those members cannot be resolved. In your particular case, the call to the KendoUI MVC extension method ToDataSourceResult() and its subsequent call to ModelState.IsValid was the culprit.

The reason this all works without error in your application is because your project is configured by default, as part of the Visual Studio ASP.NET MVC project template, to redirect assembly bindings so that the runtime targets the most recent version of ASP.NET MVC assemblied. You can fix your test project by adding a the same runtime binding information in its App.config file:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
                <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

I hope that helps.

like image 93
Kevin Babcock Avatar answered Oct 03 '22 01:10

Kevin Babcock