2012-09-26 120 views
4

我正在使用AutoFixture嘗試測試我的控制器的WebApi網站。我正在使用Moq的AutoData功能,如Ploeh's blog所述。Autofixture和WebApi控制器

我的控制器在構造函數中需要一個IDepartmentManager。下面是我的測試:

[Theory, AutoMoqData] 
public void GetCallsManagerCorrectly(
    [Frozen]Mock<IDepartmentManager> departmentManagerMock, 
    DepartmentsController sut) 
{ 
    // Fixture setup 
    // Exercise system 
    sut.Get(); 
    // Verify outcome 
    departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1)); 
    // Teardown 
} 

當我運行這個測試失敗,出現以下:

GetCallsManagerCorrectly失敗:
System.InvalidOperationException:已引發異常,同時 獲取數據的理論 Provision.Tests.WebApiControllerTests.DepartmentControllerTests.GetCallsManagerCorrectly: System.Reflection.TargetInvocationException:異常已被調用的目標引發 。 ---> System.ArgumentException:只允許使用 'http'和'https'方案。參數名:在 System.Net.Http.HttpRequestMessage.set_RequestUri(URI值)

首先價值,這是仍然是有效的,建議的方式來寫這些測試?我喜歡它讓所有事物變得多小。

其次,我應該怎麼做才能解決這個問題?如果我改變我的測試,以這樣的:

[Theory, AutoMoqData] 
public void GetCallsManagerCorrectly(
    [Frozen]Mock<IDepartmentManager> departmentManagerMock) 
{ 
    // Fixture setup 
    DepartmentsController sut = 
     new DepartmentsController(departmentManagerMock.Object); 
    // Exercise system 
    sut.Get(); 
    // Verify outcome 
    departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1)); 
    // Teardown 
} 

它通過,但後來我失去了讓控制器自動建立起來,仍然是確定的,如果我添加參數構造函數的能力。

回答

4

這絕對是使用AutoFixture編寫測試的推薦方式。這個問題很容易解決。

而不是如博客文章中所述實現[AutoMoqData]屬性,我建議創建一個稍微不同的屬性和定製 - 一組基本上將作爲整個單元測試項目的一組約定。我總是這樣做,而且我總是竭盡全力爲一個單元測試項目提供一套約定。一套約定幫助我保持我的測試(和SUT)一致。

public class AutoMyWebApiDataAttribute : AutoDataAttribute 
{ 
    public AutoMyWebApiDataAttribute() 
     : base(new Fixture().Customize(new MyWebApiCustomization())) 
    { 
    } 
} 

的MyWebApiCustomization可以定義是這樣的:

public class MyWebApiCustomization : CompositeCustomization 
{ 
    public MyWebApiCustomization() 
     : base(
      new HttpSchemeCustomization(), 
      new AutoMoqCustomization(), 
     ) 
    { 
    } 

    private class HttpSchemeCustomization : ICustomization 
    { 
     public void Customize(IFixture fixture) 
     { 
      fixture.Inject(new UriScheme("http")); 
     } 
    } 
} 

注意額外HttpSchemeCustomization類 - 應該做的伎倆。

請注意,the order of Customizations matters

+0

感謝您的快速和正確的迴應。很棒。 –

+0

@BrianMcCord和其他人很確定上面的'HttpSchemeCustomization'現在是AF V3 +中的固有功能。 –