2010-07-07 6 views
2

Hier, j'ai re-factorisé la méthode ci-dessous pour retourner soit une vue complète ou une vue partielle.Mocking et Stubbing Ajax demandes

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

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

Mais maintenant, mes tests ont rompu, ils ne parviennent pas à la déclaration if. Je l'ai fait un google et trouvé, vous pouvez railler/Stub les requêtes HTTP avec quelque chose comme,

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

Je mis en œuvre ci-dessus dans mon test et il est encore tomber.

ESSAI

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

erreur

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 

Comment puis-je obtenir la demande dans le Request.IsAjaxRequest() dans mon contrôleur pour passer comme une demande de paiement ajax ???

Cordialement Rich

Modifier - Trouvé this après, mon test ajax est en train de passer, mais ma non-ajax ne parvient toujours pas.

Répondre

1

Vous devriez probablement créer une interface comme celui-ci, qui est facile à mettre en œuvre et maquette:

public interface IRequestInfo 
{ 
    bool IsAjaxRequest { get; } 
} 

Ensuite, votre classe pourrait ressembler à ceci:

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

Et vos tests devient:

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

Notez que votre test ne concerne plus les en-têtes HTTP. Ce sont une préoccupation interne de l'implémentation IRequestInfo. Et puisque cette implémentation sera juste un wrapper fin autour de l'objet ASP.NET HttpContext.Request, il n'est pas nécessaire de le tester unitaire.

+0

Travaillé un rêve, n'avait pas pensé à le faire de cette façon. Je suppose qu'il fallait une nouvelle paire d'yeux. –