nUnit测试控制器扩展方法 [英] nUnit testing a controller extension method
问题描述
UX控件框架要求MVC控制器上的扩展方法.当nUnit尝试调用该方法(用于将部分视图打包到Json中)时,将引发一个空对象引用.
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).
该框架的作者建议通过接口调用该方法,但这只是推迟了null错误.
The author of the framework suggested calling that method through an interface, however that just postpones the null error.
是否可以使用扩展方法从控制器测试ActionResult?
Is there a way to test the ActionResult from a controller that uses an extension method?
Controller Create()方法从扩展方法返回结果部分:
The Controller Create() method returns the resulting partial from the extension method:
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.'
结果StackTrace:
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.
集成测试设置":
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;
推荐答案
看来,被测对象可能与第三者的实施担忧紧密相关,这使得孤立地进行测试变得困难.
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.
这篇关于nUnit测试控制器扩展方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!