nUnit testing a controller extension method

2019-02-21 04:06发布

UX controls framework I'm using requires an extension method on MVC controllers. A null object reference is thrown when nUnit tries to call that method (used in order to package a partial view into Json).

The author of the framework suggested calling that method through an interface, however that just postpones the null error.

Is there a way to test the ActionResult from a controller that uses an extension method?

The Controller Create() method returns the resulting partial from the extension method:

return Json(new { Content = viewRender.RenderPartialView(this, "ListItems/SimpleSyllabi", new[] { nS }) });

The extension method signature is

 public static string RenderPartialView(this Controller controller, string viewName, object model = null, bool removeWhiteSpace = true);

Error is a simple:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Result StackTrace:

at System.Web.Mvc.VirtualPathProviderViewEngine.FindPartialView(ControllerContext controllerContext, String partialViewName, Boolean useCache)
   at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClass2.<FindPartialView>b__0(IViewEngine e)
   at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths)
   at System.Web.Mvc.ViewEngineCollection.FindPartialView(ControllerContext controllerContext, String partialViewName)
   at Omu.AwesomeMvc.ControllerExtensions.RenderView(Controller controller, String viewName, Object model, String master, Boolean partial, Boolean removeWhiteSpace)
   at Omu.AwesomeMvc.ControllerExtensions.RenderPartialView(Controller controller, String viewName, Object model, Boolean removeWhiteSpace)
   at Flipprs.nUnitHelpers.Awesome.ViewRender.RenderPartialView(Controller controller, String viewName, Object model, Boolean removeWhiteSpace) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Web\Helpers\Awesome\nUnitHelpers.cs:line 17
   at Flipprs.Controllers.SyllabusAjaxListController.Create(SyllabusCreateViewModel scvm) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Web\Controllers\SyllabusAjaxListController.cs:line 217
   at Flipprs.Tests.Controllers.SyllabusAjaxListControllerTest.SyllabusAjaxListController_CreatePUT_ReturnsJson(String HTTPreqAUEmail) in A:\Stephan\Source\Workspaces\AchievementCards\Develop-Payment(v0.0.11.0)\Flipprs.Tests\Controllers\SyllabusAjaxListControllerTest.cs:line 484
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.

The Integration Test 'Setup':

 private IViewRender viewRender;

viewRender = new ViewRender();



controller = new SyllabusAjaxListController(viewRender, photoPlaceholderService, activityService, syllabusService,
            userService, organisationService, userManager);

Then in the test (excerpts)

  [Test, Sequential]
            public void SyllabusAjaxListController_CreatePUT_ReturnsJson()
{
    ActionResult result_ar = controller.Create(validModel);

            JsonResult result = result_ar as JsonResult;
}

Integration Test Mocks

        Mock<ControllerContext> controllerContext;
        Mock<HttpContext> httpContext;
        Mock<HttpContextBase> contextBase;
        Mock<HttpRequestBase> httpRequest;
        Mock<HttpResponseBase> httpResponse;

        Mock<IIdentity> identity;
        Mock<IPrincipal> principal;
        Mock<GenericPrincipal> genericPrincipal;

1条回答
We Are One
2楼-- · 2019-02-21 04:31

It appears the subject under test may be tightly coupled to 3rd party implementation concerns that make testing it in isolation difficult.

I suggest mocking the view render abstraction referred to in your original statement

public interface IViewRender {
    string RenderPartialView(Controller controller, string viewName, object model = null, bool removeWhiteSpace = true);
}

to return a string when invoked so that the method under test can flow to completion and you can assert you expected behavior.

//Arrange

//...

var viewRenderMock = new Mock<IViewRender>(); //Using Moq mocking framework
viewRenderMock
    .Setup(_ => _.RenderPartialView(It.IsAny<Controller>(), It.IsAny<string>(), It.IsAny<object>(), true))
    .Returns("some fake view string");

//...

var controller = new SyllabusAjaxListController(viewRenderMock.Object,...) {
    //...
};

//Act
var result = controller.Create(validModel) as JsonResult;

//Assert
result.Should().NotBeNull(); //FluentAssertions

//...other assertions.
查看更多
登录 后发表回答