昨天我重新考虑了以下方法,以返回完整视图或部分视图。
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仍然失败。
答案 0 :(得分: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
对象的一个薄包装,因此无需对其进行单元测试。