2017-06-06 66 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