ahs*_*ele 11 c# tdd asp.net-mvc automapper mvccontrib-testhelper
我试图测试Index
控制器的动作.该操作使用AutoMapper将域Customer
对象映射到视图模型TestCustomerForm
.虽然这有效但我担心测试我从Index
行动中收到的结果的最佳方法.
控制器的索引操作如下所示:
public ActionResult Index()
{
TestCustomerForm cust = Mapper.Map<Customer,
TestCustomerForm>(_repository.GetCustomerByLogin(CurrentUserLoginName));
return View(cust);
}
Run Code Online (Sandbox Code Playgroud)
它TestMethod
看起来像这样:
[TestMethod]
public void IndexShouldReturnCustomerWithMachines()
{
// arrange
var customer = SetupCustomerForRepository(); // gets a boiler plate customer
var testController = CreateTestController();
// act
ViewResult result = testController.Index() as ViewResult;
// assert
Assert.AreEqual(customer.MachineList.Count(),
(result.ViewData.Model as TestCustomerForm).MachineList.Count());
}
Run Code Online (Sandbox Code Playgroud)
在CreateTestController
我Rhino.Mocks
用来模拟客户存储库并将其设置为从中返回客户的方法中SetupCustomerForRepository
.通过这种方式,我知道存储库将在Index
操作调用时返回目标客户_repository.GetCustomerByLogin(CurrentUserLoginName)
.因此,我认为断言相等的数量足以满足IndexShouldReturnCustomerWithMachines
.
所有这些都说我担心我应该测试什么.
result.ViewData.Model as TestCustomerForm
.这真的是一个问题吗?这让我很担心,因为在这种情况下,我并没有真正进行测试驱动的开发,似乎我指望一个特定的实现来满足测试.TestCustomerForm
吗?Jim*_*ard 15
这是我们将AutoMapper移动到自定义ActionResult或ActionFilter的原因之一.在某些时候,您只想测试您将Foo映射到FooDto,但不一定要测试实际的映射.通过将AutoMapper移动到图层边界(例如控制器和视图之间),您只需测试您告诉AutoMapper要执行的操作.
这类似于测试ViewResult.您不从控制器测试视图是否已呈现,而是您告诉MVC呈现此类视图.我们的行动结果变为:
public class AutoMapViewResult : ActionResult
{
public Type SourceType { get; private set; }
public Type DestinationType { get; private set; }
public ViewResult View { get; private set; }
public AutoMapViewResult(Type sourceType, Type destinationType, ViewResult view)
{
SourceType = sourceType;
DestinationType = destinationType;
View = view;
}
public override void ExecuteResult(ControllerContext context)
{
var model = Mapper.Map(View.ViewData.Model, SourceType, DestinationType);
View.ViewData.Model = model;
View.ExecuteResult(context);
}
}
Run Code Online (Sandbox Code Playgroud)
使用基本控制器类上的辅助方法:
protected AutoMapViewResult AutoMapView<TDestination>(ViewResult viewResult)
{
return new AutoMapViewResult(viewResult.ViewData.Model.GetType(), typeof(TDestination), viewResult);
}
Run Code Online (Sandbox Code Playgroud)
然后,控制器现在只指定要映射到/来自的内容,而不是执行实际映射:
public ActionResult Index(int minSessions = 0)
{
var list = from conf in _repository.Query()
where conf.SessionCount >= minSessions
select conf;
return AutoMapView<EventListModel[]>(View(list));
}
Run Code Online (Sandbox Code Playgroud)
此时,我只需要测试,"确保将此Foo对象映射到此目标FooDto类型",而无需实际执行映射.
编辑:
以下是测试代码段的示例:
var actionResult = controller.Index();
actionResult.ShouldBeInstanceOf<AutoMapViewResult>();
var autoMapViewResult = (AutoMapViewResult) actionResult;
autoMapViewResult.DestinationType.ShouldEqual(typeof(EventListModel[]));
autoMapViewResult.View.ViewData.Model.ShouldEqual(queryResult);
autoMapViewResult.View.ViewName.ShouldEqual(string.Empty);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2288 次 |
最近记录: |