Mocking Ajax.IsRequest to return False

烂漫一生 提交于 2019-12-14 02:33:18

问题


I am trying to mock the Ajax.IsRequest() method of ASP.Net MVC. I found out how to do it in order for it to return true:

Expect.Call(_myController.Request.Headers["X-Requested-With"]).Return("XMLHttpRequest").Repeat.Any();

This works and returns true. Now I need to test the other branch of the code. How can I mock it to return false? I have tried removing the mock altogether, It fails with:

System.NullReferenceException : Object reference not set to an instance of an object.]

If I do:

Expect.Call(_templateReportController.Request["X-Requested-With"]).Return(null).Repeat.Any();

It fails with the same error.

Entire Test:

  /// <summary>
    /// Tests the Edit Action when calling via Ajax
    /// </summary>
    [Test]
    public void Test_Edit_AjaxRequest()
    {
        Group group = new Group();
        group.ID = 1;
        group.Name = "Admin";
        IList<Group> groupList = new List<Group>() { group };

        Definition def  = new Definition();
        def.ID = 1;
        def.Name = "Report";
        def.LastModified = DateTime.UtcNow;
        def.Groups.Add(group);


        using (_mocks.Record())
        {
            Expect.Call(_myController.Request["X-Requested-With"]).Return("XMLHttpRequest").Repeat.Any();
            Expect.Call(_DefBiz.GetAll<Group>()).Return(groupList);
            Expect.Call(_DefBiz.Get<Definition>(1)).Return(def);
        }

        myController.DefAccess = _DefBiz;
        PartialViewResult actual;

        using (_mocks.Playback())
        {
            actual = (PartialViewResult)myController.Edit(1);
        }


    }

Any advices? Cheers


回答1:


The reason your are getting NullReferenceException is because you never stubbed the controller.Request object in your unit test and when you invoke the controller action which uses Request.IsAjaxRequest() it throws.

Here's how you could mock the context using Rhino.Mocks:

[TestMethod]
public void Test_Ajax()
{
    // arrange
    var sut = new HomeController();
    var context = MockRepository.GenerateStub<HttpContextBase>();
    var request = MockRepository.GenerateStub<HttpRequestBase>();
    context.Stub(x => x.Request).Return(request);
    // indicate AJAX request
    request.Stub(x => x["X-Requested-With"]).Return("XMLHttpRequest");
    sut.ControllerContext = new ControllerContext(context, new RouteData(), sut);

    // act
    var actual = sut.Index();

    // assert
    // TODO: ...
}

[TestMethod]
public void Test_Non_Ajax()
{
    // arrange
    var sut = new HomeController();
    var context = MockRepository.GenerateStub<HttpContextBase>();
    var request = MockRepository.GenerateStub<HttpRequestBase>();
    context.Stub(x => x.Request).Return(request);
    sut.ControllerContext = new ControllerContext(context, new RouteData(), sut);

    // act
    var actual = sut.Index();

    // assert
    // TODO: ...
}

And here's a better alternative (which I would personally recommend you) in order to avoid all the plumbing code. Using MVCContrib.TestHelper (which is based on Rhino.Mocks) your unit test might be simplified to this:

[TestClass]
public class HomeControllerTests : TestControllerBuilder
{
    private HomeController _sut;

    [TestInitialize()]
    public void MyTestInitialize() 
    {
        _sut = new HomeController();
        this.InitializeController(_sut);
    }

    [TestMethod]
    public void HomeController_Index_Ajax()
    {
        // arrange
        _sut.Request.Stub(x => x["X-Requested-With"]).Return("XMLHttpRequest");

        // act
        var actual = _sut.Index();

        // assert
        // TODO: ...
    }

    [TestMethod]
    public void HomeController_Index_Non_Ajax()
    {
        // act
        var actual = _sut.Index();

        // assert
        // TODO: ...
    }
}

Much prettier. It also allows you to write much more expressive asserts on the action results. Checkout the doc or ask if for more info is needed.




回答2:


Expect.Call(_myController.Request.Headers["X-Requested-With"]).Return("SpitAndDuctTape").Repeat.Any();

...should do the job.



来源:https://stackoverflow.com/questions/3068589/mocking-ajax-isrequest-to-return-false

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!