Beim Injizieren von zwei konkreten Instanzen überschreibt die zweite Instanz die erste.
Beim Injizieren einer konkreten Instanz gefolgt von einer simulierten Instanz überschreibt die zweite Instanz die erste nicht.
Dies macht die Idee, einige Tests durchzuführen, die einen Mock verwenden, und einige Tests, die eine Implementierung verwenden (mit einem Testklassenkonstruktor, um eine Befestigung zwischen Tests zu teilen) ziemlich umständlich.
Beim Injizieren von zwei konkreten Instanzen überschreibt die zweite Instanz die erste.
Beim Injizieren einer konkreten Instanz, gefolgt von einer simulierten Instanz, überschreibt die zweite Instanz die erste.
```C#
mit System.Collections.Generic;
Verwenden von AutoFixture;
mit AutoFixture.AutoMoq;
unter Verwendung von Moq;
mit Xunit;
Namespace SomeNamespace
{
öffentliche Klasse AutoFixtureTests
{
[Tatsache]
// Geht vorbei
public void Should_OverridePreviouslyInjectedString()
{
const string test1 = "test1";
const string test2 = "test2";
var fixture = new Fixture();
fixture.Inject(test1);
fixture.Inject(test2);
Assert.Equal(fixture.Create<string>(), test2);
}
[Fact]
// Fails
public void Should_OverridePreviouslyInjectedInstance()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var sut1 = new List<int>();
fixture.Inject<IList<int>>(sut1);
fixture.Freeze<Mock<IList<int>>>();
var sut2 = fixture.Create<IList<int>>();
Assert.NotSame(sut1, sut2);
}
}
}
```
Hallo @charles-lachs,
Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu melden.
Das Verhalten, das Sie beobachten, ist _by design_. Erlauben Sie mir zu erklären. 🙂
Wenn Sie sich die Implementierung der Methode Freeze<T>
ansehen:
var value = fixture.Create<T>();
fixture.Inject(value);
return value;
Sie werden sehen, dass es lediglich ein Exemplar von T
und es in das Gerät injiziert. Tatsächlich ist die Methode Freeze
eine praktische Abkürzung für genau diesen Vorgang. Wie @ploeh in seinem Beitrag zur Einführung der Freeze-Methode im Jahr 2010 schrieb:
Es stellte sich heraus, dass wir dieses Codierungsidiom so häufig verwendet haben, dass wir beschlossen haben, es in einer praktischen Methode zu kapseln. Nach einigen Diskussionen kamen wir auf den Namen Freeze, da wir im Wesentlichen eine einzelne anonyme Variable im Gerät einfrieren und den Standardalgorithmus zum Erstellen neuer Instanzen umgehen.
Angesichts dessen sollte es nicht überraschen, dass das Einfrieren desselben Typs T
wie eine injizierte Instanz dieselbe Instanz ergibt.
Um nun auf Ihren Punkt einzugehen:
Dies macht die Idee, einige Tests durchzuführen, die einen Mock verwenden, und einige Tests, die eine Implementierung verwenden (mit einem Testklassenkonstruktor, um eine Befestigung zwischen Tests zu teilen) ziemlich umständlich.
Da ein Fixture den _Kontext_ repräsentiert, in dem ein Test ausgeführt wird, _können_ Sie sicherlich mehrere Tests dieselbe Fixture verwenden ; Dies geht jedoch auf Kosten der Vermischung mehrerer – und möglicherweise widersprüchlicher – Bedenken.
Das xUnit Patterns-Buch fasst es gut zusammen :
Das größte Problem bei einem gemeinsam genutzten Gerät besteht darin, dass es zu "Kollisionen" zwischen Tests kommen kann, die möglicherweise zu fehlerhaften Tests führen , da Tests von den Ergebnissen anderer Tests abhängen können. Ein weiteres Problem besteht darin, dass ein Fixture, das für viele Tests entwickelt wurde, zwangsläufig viel komplizierter ist als das für einen einzelnen Test erforderliche Minimal Fixture .
Diese "Kollision" ist genau das, was passiert, wenn ein Test erwartet, dass ein Objekt vom Typ T
eine bestimmte Instanz ist, während ein anderer Test erwartet, dass es sich bei T
um ein gefälschtes Objekt handelt .
Da mir kein Testszenario einfällt, bei dem es für den gleichen Typ T
Sinn macht, sowohl ein Schein _als auch_ eine konkrete Instanz zu sein (obwohl ich gerne falsch bewiesen werde), schlage ich vor, dass Sie diese haben Tests verwenden verschiedene Vorrichtungen, von denen jede so konfiguriert ist, dass sie ihr spezielles Szenario erfüllt.
Hilfreichster Kommentar
Hallo @charles-lachs,
Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu melden.
Das Verhalten, das Sie beobachten, ist _by design_. Erlauben Sie mir zu erklären. 🙂
Wenn Sie sich die Implementierung der Methode
Freeze<T>
ansehen:Sie werden sehen, dass es lediglich ein Exemplar von
T
und es in das Gerät injiziert. Tatsächlich ist die MethodeFreeze
eine praktische Abkürzung für genau diesen Vorgang. Wie @ploeh in seinem Beitrag zur Einführung der Freeze-Methode im Jahr 2010 schrieb:Angesichts dessen sollte es nicht überraschen, dass das Einfrieren desselben Typs
T
wie eine injizierte Instanz dieselbe Instanz ergibt.Um nun auf Ihren Punkt einzugehen:
Da ein Fixture den _Kontext_ repräsentiert, in dem ein Test ausgeführt wird, _können_ Sie sicherlich mehrere Tests dieselbe Fixture verwenden ; Dies geht jedoch auf Kosten der Vermischung mehrerer – und möglicherweise widersprüchlicher – Bedenken.
Das xUnit Patterns-Buch fasst es gut zusammen :
Diese "Kollision" ist genau das, was passiert, wenn ein Test erwartet, dass ein Objekt vom Typ
T
eine bestimmte Instanz ist, während ein anderer Test erwartet, dass es sich beiT
um ein gefälschtes Objekt handelt .Da mir kein Testszenario einfällt, bei dem es für den gleichen Typ
T
Sinn macht, sowohl ein Schein _als auch_ eine konkrete Instanz zu sein (obwohl ich gerne falsch bewiesen werde), schlage ich vor, dass Sie diese haben Tests verwenden verschiedene Vorrichtungen, von denen jede so konfiguriert ist, dass sie ihr spezielles Szenario erfüllt.