n对控制器扩展方法进行单元测试



我正在使用的UX控件框架需要在MVC控制器上使用扩展方法。当 nUnit 尝试调用该方法(用于将分部视图打包到 JSON 中)时,将抛出空对象引用。

框架的作者建议通过接口调用该方法,但这只会推迟 null 错误。

有没有办法从使用扩展方法的控制器测试操作结果?

控制器 Create() 方法返回扩展方法的结果部分:

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

扩展方法签名为

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

错误很简单:

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

结果堆栈跟踪:

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:StephanSourceWorkspacesAchievementCardsDevelop-Payment(v0.0.11.0)Flipprs.WebHelpersAwesomenUnitHelpers.cs:line 17
   at Flipprs.Controllers.SyllabusAjaxListController.Create(SyllabusCreateViewModel scvm) in A:StephanSourceWorkspacesAchievementCardsDevelop-Payment(v0.0.11.0)Flipprs.WebControllersSyllabusAjaxListController.cs:line 217
   at Flipprs.Tests.Controllers.SyllabusAjaxListControllerTest.SyllabusAjaxListController_CreatePUT_ReturnsJson(String HTTPreqAUEmail) in A:StephanSourceWorkspacesAchievementCardsDevelop-Payment(v0.0.11.0)Flipprs.TestsControllersSyllabusAjaxListControllerTest.cs:line 484
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.

集成测试"设置":

 private IViewRender viewRender;
viewRender = new ViewRender();

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

然后在测试中(摘录)

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

集成测试模拟

        Mock<ControllerContext> controllerContext;
        Mock<HttpContext> httpContext;
        Mock<HttpContextBase> contextBase;
        Mock<HttpRequestBase> httpRequest;
        Mock<HttpResponseBase> httpResponse;
        Mock<IIdentity> identity;
        Mock<IPrincipal> principal;
        Mock<GenericPrincipal> genericPrincipal;

似乎被测主题可能与第三方实现问题紧密耦合,这使得孤立测试变得困难。

我建议嘲笑您原始陈述中提到的视图渲染抽象

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

在调用时返回字符串,以便所测试的方法可以完成,并且可以断言预期的行为。

//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.

最新更新