我最近对我的mvc应用程序进行了一些重构,并意识到返回了很多静态视图。而不是让多个控制器具有仅返回视图的操作结果,我决定创建一个控制器,如果它们存在则返回静态视图,如果视图不存在则抛出404错误。
public ActionResult Index(string name)
{
ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
if (result.View == null)
ThrowNotFound("Page does not exists.");
return View(name);
}
我的问题是单元测试的正确方法是什么?我尝试了下面的代码,但我得到的错误是“RouteData必须包含一个名为'controller'且带有非空字符串值的项目。”
[Theory]
[InlineData("ContactUs")]
public void Index_should_return_view_if_view_exists(string name)
{
controller = new ContentController();
httpContext = controller.MockHttpContext("/", "~/Content/Index", "GET"); ;
var result = (ViewResult)controller.Index(name);
Assert.NotNull(result.View);
}
我的目的是让单元测试结束并获取真实视图。然后我开始怀疑是否应该使用SetupGet为FindView模拟ViewEngines并创建两个测试,其中第二个测试如果视图为null则抛出未找到的异常。
测试此功能的正确方法是什么?任何指针,示例代码或博客文章都会有所帮助。
由于
答案 0 :(得分:4)
您应该创建一个模拟的视图引擎并将其放入集合中:
[Theory]
[InlineData("ContactUs")]
public void Index_should_return_view_if_view_exists(string name)
{
var mockViewEngine = MockRepository.GenerateStub<IViewEngine>();
// Depending on what result you expect you could set the searched locations
// and the view if you want it to be found
var result = new ViewEngineResult(new [] { "location1", "location2" });
// Stub the FindView method
mockViewEngine
.Stub(x => x.FindView(null, null, null, false))
.IgnoreArguments()
.Return(result);
// Use the mocked view engine instead of WebForms
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(mockViewEngine);
controller = new ContentController();
var actual = (ViewResult)controller.Index(name);
Assert.NotNull(actual.View);
}