2017-06-06 8 views
1

J'écrivais un test unitaire pour ApiControllerConventions à partir d'un related SO question et j'ai écrit un AutoMoqApiControllerDataAttribute pour intégrer ce ICustomization dans xUnit.net.ArgumentNullException dans un test unitaire pour AutoFixture AutoDataAttribute

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

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

J'ai essayé d'écrire un test unitaire pour cet attribut comme ceci:

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

Cela échoue à l'exception de AutoDataAttribute:

System.ArgumentNullException valeur ne peut pas être nulle. Nom du paramètre: appareil à Ploeh.AutoFixture.Xunit2.AutoDataAttribute..ctor (de montage IFixture)

Je pensais que cela est lié à mon utilisation du AutoMoqDataAttribute donc je Reconvertit à la vanille Fact, même exception encore:

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

Pourquoi est-ce que je reçois l'exception? J'ai évidemment le IFixture raillé et ce n'est certainement pas nul.

+0

Impossible de reproduire. S'il vous plaît partager 'AutoMoqApiControllerDataAttribute'. –

+0

C'est en haut de ma question :) – rexcfnghk

+0

Donc c'est. Mon erreur, désolé à ce sujet. Je peux maintenant reproduire. –

Répondre

2

Lorsque vous obtenez une exception, c'est toujours une bonne idée de regarder la pile d'appels. L'exception est pas jeté AutoMoqApiControllerDataAttribute, mais 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() 

Alors que fixture n'est pas null quand il est passé à AutoMoqApiControllerDataAttribute, il est null lorsqu'il est passé à base(IFixture).

Pourquoi?

Tenir compte de l'appel à base:

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

Quelle valeur est transmis à base?

Non fixture, mais renvoie la valeur d'appeler fixture.Customize.

Le test ne définit pas de valeur de retour pour cet appel de méthode, donc Moq prend par défaut la valeur par défaut pour le type. Puisque IFixture est un type de référence, cela signifie null, et que la valeur null est ensuite passée à base.

Vous pouvez facilement résoudre le problème en configurant mockFixture avec une valeur de retour dans le test:

[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()); 
} 

Maintenant, le test passe dans mon repro.

Ce n'est pas un problème spécifique à AutoFixture. Vous pouvez le reproduire avec n'importe quel Fluent Interface.

+0

C'est tout! Je ne pouvais pas croire que j'avais raté ça! Merci! – rexcfnghk