2017-06-19 2 views
3

Haftungsausschluss gemacht wurde - das ist nicht die gleiche Frage wie How to use FakeItEasy to assert a method was not calledAssert, dass ein Anruf nicht mit einem generischen Parametern mit FakeItEasy

Erklärung

Ich habe ein Stück Code, das Material mit einem IOC-Containern registriert und ich kann FakeItEasy in meinen Tests verwenden, um sicherzustellen, dass Registrierungen vorgenommen werden.

Ich versuche herauszufinden, wie Sie sicherstellen, dass unerwartete Anrufe nicht gemacht werden.

Schnell Repo (Problem auf ein paar Testklassen eingekocht - das ist nicht eine reale Implementierung)

public class Foo 
{ 
    private readonly ICustomContainer m_CustomContainer; 

    public Foo(ICustomContainer customContainer) 
    { 
     m_CustomContainer = customContainer; 
    } 

    public void Bar() 
    { 
     m_CustomContainer.Register<IMyInterface, IMyImplementation>(); 
    } 
} 

public interface ICustomContainer 
{ 
    void Register<TInterface, TImplementation>() where TImplementation : TInterface; 
} 

public class UnitTest1 
{ 
    [Fact] 
    public void Test1() 
    { 
     //Arrange 
     ICustomContainer fake = A.Fake<ICustomContainer>(); 
     Foo objectUnderTest = new Foo(fake); 

     //Act 
     objectUnderTest.Bar(); 

     //Assert 
     A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened(); 
     //A.CallTo(() => fake.Register<???>()).MustNotHaveHappened(); //Any generic parameter apart from <IMyInterface, IMyImplementation> must not have happened 
    } 
} 

Der obige Test bestehen wird - was richtig ist. Wenn ich in Zukunft eine weitere Registrierung in der Bar() hinzufügen würde, würde es immer noch passieren - was nicht so gut ist, da mein Test nur bekannte Szenarien testet.

Was ich

So, da die Schnittstelle oben für ICustomContainer zu erreichen versuche, die meine IOC-Container ist, würde ich sicherstellen möchte, dass es nur wie erwartet genannt wird.

Was ich schon

Nachdem andere spöttische Rahmen in der Vergangenheit wie TypeMock Trenner verwendet sucht habe, konnte ich das falsche Objekt einrichten Ausnahmen zu werfen, sofern nicht spezifische (erwartete) Anrufe getätigt werden. Ich weiß nicht, ob ich das mit FakeItEasy machen kann. Auch TypeMock Isolator unterstützt .NET Core nicht, also ist es nicht gut für mich.

Wenn ich eine Methode hätte, die keinen generischen Parameter verwendet, könnte ich FakeItEasy erhalten, um zu zählen, wie oft die Methode aufgerufen wurde, und erwarte, dass sie zusätzlich zum Testen der Argumente aufgerufen wurde erwartete Anrufe. Das ist sicherlich eine Option, bedeutet aber, dass ich eine Fassade über meiner Schnittstelle erstellen muss (als Erweiterungsmethode oder Wrapper, nehme ich an), um Typparameter anstelle generischer Parameter aufzunehmen, was bedeutet, dass ich die Zeit vor der Kompilierung verliere Warnungen bekomme ich mit der generischen Parameterbeschränkung.

Die eigentliche Frage

Wie kann ich meinen Test ändern, so dass ich, dass ein unerwarteter Anruf nicht mit allen allgemeinen Parametern andere als die gemacht wurde behaupten kann ich wurde mit .NET Kern/FakeItEasy erwartet/xUnit?

Antwort

3

Ich mag übermäßig vereinfachen, aber es klingt wie ein Strict Fake kann Ihnen helfen. Machen Sie eine, dann erlauben Sie ausdrücklich, welche Anrufe Sie wollen.

//Arrange 
ICustomContainer fake = A.Fake<ICustomContainer>(x => x.Strict()); 

// allow just the registrations you want to 
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).DoesNothing(); 

Foo objectUnderTest = new Foo(fake); 

//Act 
objectUnderTest.Bar(); 

//Assert 
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened(); 
+0

Nein, Sie sind nicht zu stark vereinfachend; Ich hatte keine Ahnung, dass du das tun könntest und nachdem ich es ausprobiert habe, scheint es genau das zu sein, wonach ich suche. Gute Antwort! – Jay

+1

Ich bin froh, dass ich geholfen habe. –

Verwandte Themen