2013-08-04 77 views
2

我對使用ASP.NET MVC的可測試設計有相當深刻的理解,並且已經成功地將這種理解應用於使用ServiceStack構建可測試服務。然而,這個難題的一個非常重要的部分讓我無法迴避,我該如何單元測試依賴於JsonServiceClient的MVC動作?我知道我可以將JsonServiceClient包裝在自己的抽象中,但是有沒有基於ServiceStack的解決方案?如何對使用ServiceStack的JsonServiceClient()的ASP.NET MVC操作進行單元測試?

例如,給使用的DTO取行星列表的做作服務:

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

比方說,我有一個使用JsonServiceClient獲取數據的簡單MVC的動作,做了一些工作,然後返回鑑於與包括我的行星列表視圖模型:

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.Get(IRequest請求)沒有實現我的單元測試使用DirectServiceClient作爲我IRestClient的路徑(拋出一個NotImplementedException) 。我的測試使用NUnit和繼承ServiceStack的TestBase:

[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提供了一種策略,我認爲這對於使用ServiceStack和ASP.NET MVC的開發人員來說是一個常見的場景嗎?我是否在ServiceStack的產品範圍之外工作,也許我應該編寫自己的隱藏JsonServiceClient的抽象代碼?

我花了很多時間在網上尋找建議,雖然有很多端到端的集成測試示例,但似乎沒有特定於我正在嘗試使用單元測試的內容。

回答

0

難道你不能只是創建自己的模擬執行IRestClient?或者更好地使用像RhinoMock這樣的模擬界面並設置期望和響應?

例如,使用RhinoMock(不知道真正的語法,但它應該清楚發生了什麼):

[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... 
} 
+0

我希望ServiceStack提供了一個模擬/假執行IRestClient,具體DirectServiceClient。我同意你的建議,我可以創建自己的模擬實現,使用IoC的測試雙打或者使用像RhinoMock這樣的模擬框架。我希望ServiceStack爲我需要特別做的事情提供了一個開箱即用的解決方案 - 因爲它似乎在構建可測試客戶端時似乎不足。我想我只需要自己做一點小腿工作,建立我需要的東西,當然不是世界末日。謝謝你的建議。 –

相關問題