2017-06-06 48 views
1

我正在爲related SO question編寫ApiControllerConventions的單元測試,我寫了AutoMoqApiControllerDataAttribute將此ICustomization集成到xUnit.net中。AutoFixture AutoDataAttribute的單元測試中的ArgumentNullException

public class AutoMoqApiControllerDataAttribute : AutoDataAttribute 
{ 
    public AutoMoqApiControllerDataAttribute() : this(new Fixture()) 
    { 
    } 

    public AutoMoqApiControllerDataAttribute(IFixture fixture) : base(
     fixture.Customize(new ApiControllerConventions())) 
    { 
    } 
} 

我試着寫一個單元測試,像這樣該屬性:

public class AutoMoqDataAttribute : AutoDataAttribute 
{ 
    public AutoMoqDataAttribute() : this(new Fixture()) 
    { 
    } 

    public AutoMoqDataAttribute(IFixture fixture) : 
     base(fixture.Customize(new AutoMoqCustomization())) 
    { 
    } 
} 

[Theory, AutoMoqData] 
public void AutoMoqApiControllerDataAttribute_ContainsCorrectCustomization(
    Mock<IFixture> mockFixture) 
{ 
    // Arrange 
    mockFixture.Setup(f => f.Customize(It.IsAny<ApiControllerConventions>())).Verifiable(); 

    // Act 
    var sut = new AutoMoqApiControllerDataAttribute(mockFixture.Object); 

    // Assert 
    mockFixture.Verify(f => f.Customize(It.IsAny<ApiControllerConventions>()), Times.Once); 
} 

這種失敗與AutoDataAttribute一個例外:

System.ArgumentNullException 值不能爲空。 參數名:燈具 在Ploeh.AutoFixture.Xunit2.AutoDataAttribute..ctor(IFixture夾具)

我想到了AutoMoqDataAttribute所以我恢復到香草Fact,相同的異常還是這關係到我的用法:

[Fact] 
public void AutoMoqApiControllerDataAttribute_ContainsCorrectCustomization() 
{ 
    // Arrange 
    var mockFixture = new Mock<IFixture>(); 
    mockFixture.Setup(f => f.Customize(It.IsAny<ApiControllerConventions>())).Verifiable(); 

    // Act 
    var sut = new AutoMoqApiControllerDataAttribute(mockFixture.Object); 

    // Assert 
    mockFixture.Verify(f => f.Customize(It.IsAny<ApiControllerConventions>()), Times.Once); 
} 

爲什麼我會得到異常?我顯然有IFixture嘲笑,它絕對不是空的。

+0

無法重現。請分享'AutoMoqApiControllerDataAttribute'。 –

+0

它在我的問題的頂部:) – rexcfnghk

+0

所以它是。我的錯誤,對此感到遺憾。我現在可以重現。 –

回答

2

當您收到異常時,查看調用堆棧總是一個好主意。唯一的例外是不是在AutoMoqApiControllerDataAttribute拋出,但在AutoDataAttribute

System.ArgumentNullException : Value cannot be null. 
Parameter name: fixture 
    at Ploeh.AutoFixture.Xunit2.AutoDataAttribute..ctor(IFixture fixture) 
    AutoMoqApiControllerDataAttribute.cs(12,0): at _44380395.AutoMoqApiControllerDataAttribute..ctor(IFixture fixture) 
    Tests.cs(22,0): at _44380395.Tests.AutoMoqApiControllerDataAttribute_ContainsCorrectCustomization() 

雖然fixture不是null當它傳遞給AutoMoqApiControllerDataAttribute,它null傳遞給base(IFixture)時。

爲什麼?

考慮調用base

base(fixture.Customize(new ApiControllerConventions())) 

哪個值被傳遞給base

不是fixture,而是從調用fixture.Customize返回值

測試不會爲此方法調用設置返回值,因此Moq默認爲該類型的默認值。由於IFixture是參考類型,這意味着null,並且null值然後傳遞到base

您可以輕鬆地使用在測試一個返回值配置mockFixture解決的問題:

[Fact] 
public void AutoMoqApiControllerDataAttribute_ContainsCorrectCustomization() 
{ 
    // Arrange 
    var mockFixture = new Mock<IFixture>(); 
    mockFixture 
     .Setup(f => f.Customize(It.IsAny<ApiControllerConventions>())) 
     .Returns(mockFixture.Object) 
     .Verifiable(); 

    // Act 
    var sut = new AutoMoqApiControllerDataAttribute(mockFixture.Object); 

    // Assert 
    mockFixture.Verify(
     f => f.Customize(It.IsAny<ApiControllerConventions>()), 
     Times.Once()); 
} 

現在測試通過我的攝製。

這不是特定於AutoFixture的問題。您可以使用任何Fluent Interface進行復制。

+0

就是這樣!我簡直不敢相信我錯過了!謝謝! – rexcfnghk