2010-07-07 56 views
2

昨天我重新考虑了以下方法以返回完整视图或部分视图。嘲弄和剔除Ajax请求

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

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

但是现在我的测试已经破坏,它们在if声明上失败。我已经做了谷歌和发现你可以模拟/存根的东西,如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 }; 

我实现上面的在我的测试,它仍然倾倒。

TEST

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

ERROR

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 

我如何在我的控制器中的Request.IsAjaxRequest()请求传递作为一个Ajax请求???

问候 丰富

编辑 - 发现this后,我的AJAX测试合格,现在可是我的非Ajax仍然失败。

回答

1

你或许应该创建这样一个接口,这是很容易实现和模拟:

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标题有关。这些是IRequestInfo实施的内部关注点。而且由于该实现只是围绕ASP.NET HttpContext.Request对象的简单包装,因此不需要对其进行单元测试。

+0

做了一个梦,没有想过这样做。我想它需要一双新鲜的眼睛。 – 2010-07-07 15:06:04