MVC4的发布版本似乎发生了一些变化,导致在单元测试中测试操作结果时,无法调用自定义操作结果中的ExecuteResult方法。
这里有一个非常做作的例子,它适用于MVC3和MVC4的早期版本。从单元测试运行时,执行结果从不"执行"。我在这里错过了什么?其他人看到这种行为了吗?
行动结果
public class SomeActionResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("null context");
}
var view = new ViewResult {ViewName = "index"};
view.ExecuteResult(context);
}
}
控制器操作
[HttpPost]
public ActionResult Index(string something)
{
return new SomeActionResult();
}
单元测试(使用MVCContrib)
[Test]
public void ShouldWork_but_doesnt_in_mvc4()
{
var controller = new HomeController();
var result = controller.Index("test");
result.AssertViewRendered();
}
这里有一个非常做作的例子,它适用于MVC3和MVC4的早期版本。
你一定搞错了什么。这在MVC 3、2、1中也不起作用。这是意料之中的事。因为单元测试意味着你正在孤立地对某些东西进行单元测试。因此,您有一个控制器操作的单元测试,另一个测试您的自定义操作结果。
不是Index
操作正在对操作结果调用ExecuteResult
结果方法。在用户请求的执行过程中,这种情况发生在MVC执行管道的更高层。在单元测试中,您只是简单地调用Index
方法。
因此,为了对这个控制器操作进行单元测试,您只需断言它返回正确类型的操作结果:
[Test]
public void Ensure_That_Index_Action_Return_SomeActionResult()
{
// arrange
var controller = new HomeController();
// act
var result = controller.Index("test");
// assert
result.AssertResultIs<SomeActionResult>();
}
在SomeActionResult
的另一个单元测试中,您将手动调用ExecuteResult方法,并断言此自定义操作结果使用了ViewResult
。
此外,从ViewResult派生自定义操作结果似乎更合适,而不是在ExecuteResult方法中手动实例化ViewResult并设置ViewName:
public class SomeActionResult : ViewResult
{
public override void ExecuteResult(ControllerContext context)
{
this.ViewName = "Index";
base.ExecuteResult(context);
}
}