Frage

Ich versuche SUT Fabrik 'Muster' zu verwenden, meinen SUT zu erstellen.

In Anbetracht der SUT Struktur:

namespace MySut
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2 )
        {
        }
    }
}

Ich bin mit AutoFixture , und frage mich, was ist der beste Weg, um die folgenden Spezifikationen und die damit verbundenen SUT zum Einsturz Factory-Methode [wertvoll, aber] busywork:

namespace MySpecifications
{
    using MySut;
    public class MySpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( )
        {
            return CreateSut( CreateDep1(), CreateDep2() );
        }

        private object CreateSut( Dep1 dep1 )
        {
            return CreateSut( dep1, CreateDep2() );
        }

        private object CreateSut( Dep2 dep2 )
        {
            return CreateSut( CreateDep1(), dep2 );
        }

        private Sut CreateSut( Dep1 dep1, Dep2 dep2 )
        {
            return new Sut( dep1, dep2 );
        }

        private static Dep1 CreateDep1()
        {
            return new Fixture().CreateAnonymous<Dep1>();
        }

        private static Dep2 CreateDep2()
        {
            return new Fixture().CreateAnonymous<Dep2>();
        }
    }
}

, um so etwas wie:

    public class MyAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( params object[] injectedNonAnonymouses )
        {
            return new Fixture(  ).Build<Sut>(  )./*??????*/;
        }
    }

oder:

    public class MyAnticipatedAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = new Fixture(  ).Build<Sut>().CreateAnonymous(  );
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep1>().Object )*/.CreateAnonymous();
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep2>().Object )*/.CreateAnonymous();
        }
    }
.

das heißt, die ganze Fabrik Junk entfernen, so dass meine Daten können leicht mit einem Übergang bewältigen zu:

namespace MySutWithNewDependency
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Dep3
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2, Dep3 dep3 )
        {
        }
    }
}

Während es mit der Vorstellung eines automocking Containers ist überlappen, ich suche immer noch nicht für einen goldenen Hammer - nur einen Weg, die Lage sein, zu verspotten 0 oder 1, was zu einer Zeit, und noch in der Lage seiner Schaffung abhängig anpassen Objekte ohne explizite Aufrufe an das SUT Konstruktor, wenn seine Satz von Abhängigkeiten Änderungen zu überdenken zu müssen.

(auch mit xUnit.net (subspec Stil), Moq, Ninject2 (obwohl Sie nicht will in meinen Spezifikationen DI verwenden))

War es hilfreich?

Lösung

AutoFixture mehr oder weniger für Sie all dies tun, ohne alle, dass zusätzliche Gerüste. Ich würde mit einem grundlegenden Fixture beginnen und verwenden Sie es zu lösen Sut:

var fixture = new Fixture();
var sut = fixture.CreateAnonymous<Sut>();

Dies setzt voraus, dass Dep1 und Dep2 automatisch durch AutoFixture erstellt werden, sondern als dargestellt, können sie, weil sie Standardkonstruktoren haben.

Wenn Sie eine bestimmte Art außer Kraft setzen möchten, können Sie die Register-Methode wie folgt verwenden:

var fixture = new Fixture();

var mock = new Mock<Dep1>();
fixture.Register(mock.Object);
// Setup mock if necessary...

var sut = fixture.CreateAnonymous<Sut>();

Dies wird dazu führen, fixture Gebrauch mock.Object jederzeit Dep1 benötigt wird, auch wenn der Sut Konstruktor aufgerufen wird. Dies ist definitiv passt Ihre Anforderung angesichts der sich entwickelnden Konstrukteurs robust zu sein, und einer der Hauptgründe, AutoFixture wie das gebaut wurde.

In einem realistischeren Szenario DEP1 und DEP2 könnten Schnittstellen sein, in welchem ??Fall Sie könnte sie als Teil eines ‚Standard-Fixture‘ registrieren. Dies ist sicherlich möglicherweise auch, weil das letzte Aufruf Register gewinnt . Dies bedeutet, dass Sie eine Fixture-Instanz mit einigen guten Standardeinstellungen konfigurieren können und nach wie vor bestimmte Typen außer Kraft setzen können, wenn Sie dies tun müssen, um.

Ich persönlich AutoFixture als Auto spöttische Behälter verwenden. diese Diskussion einen Hinweis darauf, wie sieht das mit dem AutoFixture möglich wäre 1.1 API, aber der neue Kernel für AutoFixture 2.0 Optionen viel bessere Erweiterbarkeit bieten. Als ich um es zu bekommen, werde ich eine Blog-Post zu diesem Thema schreiben.

P. S. Sorry über die späte Antwort, aber ich habe Ihre Frage nicht vor jetzt. In Zukunft können Sie mich ping (z auf Twitter) für eine schnellere Antwort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top