开发者

Mocking Ajax.IsRequest to return False

开发者 https://www.devze.com 2023-01-03 18:11 出处:网络
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:

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>()).Re开发者_开发技巧turn(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


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.


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

...should do the job.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号