单元测试自定义操作导致MVC4未调用executesort



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);
    }
}

最新更新