c# - 模拟和 stub Ajax 请求

标签 c# asp.net-mvc rhino-mocks mspec

昨天我重构了以下方法以返回完整 View 或部分 View 。

public ActionResult List(int page)
{
    var viewModel = GetListViewModel(page);

    if(Request.IsAjaxRequest())
    {
        return PartialView("_list", viewModel);
    }
     return View("PartsList", viewModel);
}

但现在我的测试失败了,它们在 if 语句上失败了。我做了一个谷歌,发现你可以用类似的东西模拟/ stub HTTP 请求,

HttpContextBase mockedContext = MockRepository.GeneratePartialMock<HttpRequestBase>();
HttpRequestBase mockedContext = MockRepository.GeneratePartialMock<HttpContextBase>();

mockedContext.Stub(x => x.Request).Return(mockedRequest);
mockedRequest.Stub(r => r["X-Requested-With"]).Return("");

subject.ControllerContext = new ControllerContext { HttpContext = mockedContext };

我在我的测试中实现了上面的内容,但它仍然在倒下。

测试

public class when_asked_for_the_parts_list_view : context_for_part_controller
{
    static ActionResult _result;
    static IPagination<Part> _parts;
    static PartListPageViewModel _partListPageViewModel;

    Establish context = () =>
    {
         mockedContext.Stub(x => x.Request).Return(mockedRequest);
         mockedRequest.Stub(r => r["X-Requested-With"]).Return("XMLHttpRequest");
         subject.ControllerContext = new ControllerContext { HttpContext = mockedContext };

         _parts = new List<Part>().AsPagination(1);
         _partListPageViewModel = new PartListPageViewModel();

         _partTasks.Stub(x => x.GetParts(1)).Return(_parts);
         _listMapper.Stub(x => x.MapFrom(_parts)).Return(_partListPageViewModel);
    };

    Because of = () =>
    {
        _result = subject.List(1);
    };

    It should_retreve_the_parts =
        () => _partTasks.AssertWasCalled(x=>x.GetParts(1));

    It should_map_the_parts_to_a_viewModel =
        () => _listMapper.AssertWasCalled(x => x.MapFrom(_parts));

    It should_return_the_list_as_a_partialview =
        () => _result.ShouldBeAPartialView().ViewData.Model.ShouldEqual(_partListPageViewModel);
}

错误

should map the parts to a viewModel : Failed
The method or operation is not implemented.

System.NotImplementedException: The method or operation is not implemented.

at System.Web.HttpRequestBase.get_Headers()
at HttpRequestBaseProxy5a253d42dd57477f936e24736e848cbb.get_Headers_callback_47()
at HttpRequestBaseProxy5a253d42dd57477f936e24736e848cbb.Invocationget_Headers_66.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Rhino.Mocks.Impl.ReplayPartialMockState.DoMethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at HttpRequestBaseProxy5a253d42dd57477f936e24736e848cbb.get_Headers()
at System.Web.Mvc.AjaxRequestExtensions.IsAjaxRequest(HttpRequestBase request)
at Catalogue.Web.Controllers.Part.PartController.List(Int32 page) in PartController.cs: line 143
at Catalogue.MSpecTests.UI.Parts.when_asked_for_the_parts_list_view.<.ctor>b__6() in PartControllerTests.cs: line 214

如何在我的 Controller 中获取 Request.IsAjaxRequest() 中的请求作为 ajax 请求传递???

问候 丰富

编辑 - 找到 this帖子,我的 ajax 测试现在通过了,但我的非 ajax 测试仍然失败。

最佳答案

您可能应该创建一个这样的接口(interface),它易于实现和模拟:

public interface IRequestInfo
{
    bool IsAjaxRequest { get; }
}

那么你的类可能看起来像这样:

public class MyClass
{
    private readonly IRequestInfo _request;

    public MyClass(IRequestInfo request)
    {
        _request = request;
    }

    public ActionResult List(int page)
    {
        var viewModel = GetListViewModel(page);
        if (_request.IsAjaxRequest)
        {
            return PartialView("_list", viewModel);
        }
        return View("PartsList", viewModel);
    }
}

你的测试变成:

[Test]
public void List_returns_PartialView_for_Ajax_request()
{ 
   // arrange system under test and stubs
   var request = MockRepository.GenerateStub<IRequestInfo>();
   request.Stub(x => x.IsAjaxRequest).Returns(true);
   var myObject = new MyClass(request);

   // act
   object result = myObject.List(0);

   // assert
   Assert.IsTrue(result is PartialView);
}

请注意您的测试不再关注 HTTP header 。这些是 IRequestInfo 实现的内部问题。由于该实现只是 ASP.NET HttpContext.Request 对象的薄包装,因此无需对其进行单元测试。

关于c# - 模拟和 stub Ajax 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3193347/

相关文章:

C# 正则表达式匹配不跟随相同字符对的字符

c# - 单元测试删除,即使在数据库中删除了记录也返回

c# Rhino 模拟 - 这是对模拟的适当使用吗?

c# - 如何模拟 System.Data.IDataReader 中的 GetValues() 方法?

unit-testing - 使用RhinoMocks,我如何断言调用了几种方法之一?

c# - 为什么 EventHandler 在以下 asp.net 代码中不触发?

c# - 为什么我在这里得到 "Cannot access a closed Stream"?

c# - 如何摆脱异常 "The ' Microsoft.ACE.OLEDB.12。 Win 7 中的 0' provider is not registered on the local machine"

html - MVC 形式 : align Actionlink and button next to each other on same vertical alignment

javascript - 将数组从 MVC 传递到 javascript?