C# 如何对使用ServiceStack的ASP.NET MVC操作进行单元测试;s JsonServiceClient()?
在使用ASP.NET MVC时,我对可测试设计有着相当深刻的理解,并成功地将这种理解应用于使用ServiceStack构建可测试服务。然而,有一个非常重要的问题我没有解决,那就是如何对依赖于JsonServiceClient的MVC操作进行单元测试?我知道我可以在自己的抽象中包装JsonServiceClient,但是有基于ServiceStack的解决方案吗 例如,提供一个使用DTO获取行星列表的人工服务:C# 如何对使用ServiceStack的ASP.NET MVC操作进行单元测试;s JsonServiceClient()?,c#,asp.net-mvc,nunit,servicestack,C#,Asp.net Mvc,Nunit,servicestack,在使用ASP.NET MVC时,我对可测试设计有着相当深刻的理解,并成功地将这种理解应用于使用ServiceStack构建可测试服务。然而,有一个非常重要的问题我没有解决,那就是如何对依赖于JsonServiceClient的MVC操作进行单元测试?我知道我可以在自己的抽象中包装JsonServiceClient,但是有基于ServiceStack的解决方案吗 例如,提供一个使用DTO获取行星列表的人工服务: public class PlanetsService : Service {
public class PlanetsService : Service
{
public IRepository Repository { get; set; } // injected via Funq
public object Get(PlanetsRequest request)
{
var planets = Repository.GetPlanets();
return new PlanetsResponse{ Planets = planets };
}
}
假设我有一个简单的MVC操作,它使用JsonServiceClient获取数据,做一些工作,然后返回一个视图,其中包含一个视图模型,其中包括我的行星列表:
public class PlanetsController : Controller
{
private readonly IRestClient _restClient; // injected with JsonServiceClient in AppHost
public PlanetsController(IRestClient restClient)
{
_restClient = restClient;
}
public ActionResult Index()
{
var request = new PlanetsRequest();
var response = _restClient.Get(request);
// maybe do some work here that we want to test
return View(response.Planets);
}
}
我开始在单元测试中将DirectServiceClient用作我的IRestClient,但是没有实现DirectServiceClient.Get(IRequest请求)(引发NotImplementedException)。我的测试使用NUnit并从ServiceStack的测试库继承:
[TestFixture]
public class PlanetsControllerTests : TestBase
{
[Test]
public void Index_Get_ReturnsViewResult()
{
var restClient = new DirectServiceClient(this, new ServiceManager(typeof(PlanetsService).Assembly));
var controller = new PlanetsController(restClient);
var viewResult = controller.Index() as ViewResult;
Assert.IsNotNull(viewResult);
}
protected override void Configure(Funq.Container container)
{
// ...
}
}
所以我想真正的问题是:DirectServiceClient是否真的可以提供给IRestClient进行单元测试?ServiceStack是否提供了一种策略,我认为这是开发人员在ASP.NET MVC中使用ServiceStack的常见场景?我是否在ServiceStack的产品范围之外工作,也许我应该编写自己的抽象代码来隐藏JsonServiceClient
我花了很多时间在网上寻找建议,虽然有大量的端到端集成测试示例,但似乎没有一个特定于我正在尝试的单元测试。您不能创建自己的
IRestClient
模拟实现吗?或者最好使用RhinoMock之类的工具来模拟接口,并设置期望和响应
例如,使用RhinoMock(不确定真正的语法,但应该清楚发生了什么):
[测试]
public void Index_Get_ReturnsViewResult()
{
var restClient=MockRepository.GetMock();
var控制器=新的PlanetController(restClient);
restClient.Expect(c=>c.Get(null)).IgnoreArguments().Return(newplanetsresponse{/*some-fake-Planets*/});
var viewResult=controller.Index()作为viewResult;
Assert.IsNotNull(viewResult);
//在这里,你还可以断言模型中有你注入的行星列表。。。
}
我希望ServiceStack提供IRestClient的模拟/伪实现,特别是DirectServiceClient。我同意你的建议,我可以创建我自己的模拟实现,使用IoC的双重测试,或者使用类似RhinoMock的模拟框架。我希望ServiceStack有一个开箱即用的解决方案来满足我的具体需求——尽管它对测试很友好,但在构建可测试客户机方面似乎还存在不足。我想我只需要自己做一点腿部运动,建造我需要的东西,当然不是世界末日。谢谢你的建议。
[Test]
public void Index_Get_ReturnsViewResult()
{
var restClient = MockRepository.GetMock<IRestClient>();
var controller = new PlanetsController(restClient);
restClient.Expect(c => c.Get(null)).IgnoreArguments().Return(new PlanetsResponse{ /* some fake Planets */ });
var viewResult = controller.Index() as ViewResult;
Assert.IsNotNull(viewResult);
// here you can also assert that the Model has the list of Planets you injected...
}