如何使用 MSpec 测试 ASP.NET MVC 操作设置的 HTTP 状态代码

发布于 2024-12-07 01:58:28 字数 829 浏览 0 评论 0原文

我有以下控制器:

public sealed class SomeController : Controller
{
    public ActionResult PageNotFound()
    {
        Response.StatusCode = 404;

        return View("404");
    }
}

我创建了一个 MSpec 规范:

[Subject(typeof (SomeController))]
public class when_invalid_page_is_requested : SomeControllerSpec
{
    Because of = () => result = Controller.PageNotFound();

    It should_set_status_code_to_404 = 
        () => Controller.Response.StatusCode.ShouldEqual(404);
}

public abstract class SomeControllerSpec
{
    protected static HomeController Controller;

    Establish context = () => { Controller = new SomeController(); };
}

但由于我实例化控制器的方式,HttpContext 为 null。 测试由 PageNotFound 操作设置的状态代码的最佳方法是什么?

编辑:在下面发布了答案

I have the following controller:

public sealed class SomeController : Controller
{
    public ActionResult PageNotFound()
    {
        Response.StatusCode = 404;

        return View("404");
    }
}

I have created an MSpec specification:

[Subject(typeof (SomeController))]
public class when_invalid_page_is_requested : SomeControllerSpec
{
    Because of = () => result = Controller.PageNotFound();

    It should_set_status_code_to_404 = 
        () => Controller.Response.StatusCode.ShouldEqual(404);
}

public abstract class SomeControllerSpec
{
    protected static HomeController Controller;

    Establish context = () => { Controller = new SomeController(); };
}

But because of how I instantiate the controller, HttpContext is null.
What would be the best way to test status code set by the PageNotFound action?

EDIT: Posted an answer below

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安静被遗忘 2024-12-14 01:58:28

找到了一种使用最小起订量来做到这一点的方法。

[Subject(typeof (SomeController))]
public class when_invalid_page_is_requested : SomeControllerSpec
{
    Because of = () => result = Controller.PageNotFound();

    It should_set_status_code_to_404 = 
        () => HttpResponse.VerifySet(hr => hr.StatusCode = 404);
}

public abstract class SomeControllerSpec
{
    protected static SomeController Controller;
    protected static Mock<ControllerContext> ControllerContext;
    protected static Mock<HttpResponseBase> HttpResponse;

    Establish context = () =>
    {
        ControllerContext = new Mock<ControllerContext>();
        HttpResponse = new Mock<HttpResponseBase>();
        ControllerContext.SetupGet(cc => cc.HttpContext.Response)
                         .Returns(HttpResponse.Object);

        Controller = new SomeController
                         {
                             ControllerContext = ControllerContext.Object
                         };
    };
}

不是很优雅。如果您能想到更好的方法 - 请告诉我。

Found a way to do it using Moq.

[Subject(typeof (SomeController))]
public class when_invalid_page_is_requested : SomeControllerSpec
{
    Because of = () => result = Controller.PageNotFound();

    It should_set_status_code_to_404 = 
        () => HttpResponse.VerifySet(hr => hr.StatusCode = 404);
}

public abstract class SomeControllerSpec
{
    protected static SomeController Controller;
    protected static Mock<ControllerContext> ControllerContext;
    protected static Mock<HttpResponseBase> HttpResponse;

    Establish context = () =>
    {
        ControllerContext = new Mock<ControllerContext>();
        HttpResponse = new Mock<HttpResponseBase>();
        ControllerContext.SetupGet(cc => cc.HttpContext.Response)
                         .Returns(HttpResponse.Object);

        Controller = new SomeController
                         {
                             ControllerContext = ControllerContext.Object
                         };
    };
}

Not very elegant. If you can think of a better way - let me know.

寄居者 2024-12-14 01:58:28

您可以使用:

_controller.Response.StatusCode

You can use:

_controller.Response.StatusCode
魔法少女 2024-12-14 01:58:28

另一种选择是使用 MvcContrib 的 TestControllerBuilder...

var myController = new MyController();

var testControllerBuilder = new TestControllerBuilder();
testControllerBuilder.InitializeController(myController);

然后使用 NUnit(我猜 Moq 版本会起作用)就像你拥有的那样)...

myController.Response.AssertWasCalled( response => response.StatusCode = 400 );

所有丑陋的设置和模拟工作仍在完成,但由 MvcContrib 而不是在测试内部完成。这是一篇关于使用 TestControllerBuilder 的文章。

Another option using MvcContrib's TestControllerBuilder...

var myController = new MyController();

var testControllerBuilder = new TestControllerBuilder();
testControllerBuilder.InitializeController(myController);

and then using NUnit (I'd guess the Moq version would work just like you have it)...

myController.Response.AssertWasCalled( response => response.StatusCode = 400 );

All the ugly setup and mocking work is still being done, but by MvcContrib instead of inside the test. Here's a post on using the TestControllerBuilder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文