Lors de l'injection de deux instances concrètes, la seconde instance remplace la première.
Lors de l'injection d'une instance concrète, suivie d'une instance simulée, la seconde instance ne remplace pas la première.
Cela rend l'idée d'effectuer certains tests qui utilisent un simulacre et certains tests qui utilisent une implémentation (en utilisant un constructeur de classe de test pour partager un appareil entre les tests) assez maladroite.
Lors de l'injection de deux instances concrètes, la seconde instance remplace la première.
Lors de l'injection d'une instance concrète, suivie d'une instance simulée, la seconde instance remplace la première.
```C#
en utilisant System.Collections.Generic ;
en utilisant AutoFixture ;
en utilisant AutoFixture.AutoMoq ;
en utilisant Moq ;
en utilisant Xunit ;
espace de noms SomeNamespace
{
AutoFixtureTests de classe publique
{
[Fait]
// Les laissez-passer
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);
}
}
}
```
Salut @charles-salmon,
Merci d'avoir pris le temps de signaler cela.
Le comportement que vous observez est _de conception_. Permettez-moi de vous expliquer. ??
Si vous regardez l'implémentation de la méthode Freeze<T>
:
var value = fixture.Create<T>();
fixture.Inject(value);
return value;
Vous verrez que tout ce qu'il fait est de créer un spécimen de T
et de l'injecter dans le luminaire. En effet, la méthode Freeze
est apparue comme un raccourci pratique pour cette opération même. Comme @ploeh l'a écrit dans son article présentant la méthode Freeze en 2010 :
Il s'est avéré que nous avons tellement utilisé cet idiome de codage que nous avons décidé de l'encapsuler dans une méthode pratique. Après quelques débats, nous sommes arrivés au nom Freeze, car nous congelons essentiellement une seule variable anonyme dans l'appareil, contournant l'algorithme par défaut pour créer de nouvelles instances.
Compte tenu de cela, il n'est pas surprenant que le gel du même type T
qu'une instance injectée donne la même instance.
Maintenant, pour répondre à votre question :
Cela rend l'idée d'effectuer certains tests qui utilisent un simulacre et certains tests qui utilisent une implémentation (en utilisant un constructeur de classe de test pour partager un appareil entre les tests) assez maladroite.
Étant donné qu'un appareil représente le _contexte_ dans lequel un test s'exécute, vous _pouvez_ certainement avoir plusieurs tests qui partagent le même appareil ; cependant, cela se fait au prix d'un mélange de préoccupations multiples, voire conflictuelles.
Le livre xUnit Patterns le résume bien :
Le plus gros problème avec un appareil partagé est qu'il peut entraîner des "collisions" entre les tests, ce qui peut entraîner des tests erratiques , car les tests peuvent dépendre des résultats d'autres tests. Un autre problème est qu'un appareil conçu pour servir de nombreux tests est forcément beaucoup plus compliqué que l' appareil minimal requis pour un seul test.
Cette "collision" est exactement ce qui se passe lorsqu'un test s'attend à ce qu'un objet de type T
soit une instance spécifique, tandis qu'un autre test s'attend T
ce que faux objet .
Étant donné que je ne peux pas penser à un scénario de test où il est logique que le même type T
à la fois une simulation _et_ une instance concrète (bien que je sois heureux d'avoir tort), je vous suggère d'avoir ces les tests utilisent différents appareils, chacun configuré pour servir son scénario particulier.
Commentaire le plus utile
Salut @charles-salmon,
Merci d'avoir pris le temps de signaler cela.
Le comportement que vous observez est _de conception_. Permettez-moi de vous expliquer. ??
Si vous regardez l'implémentation de la méthode
Freeze<T>
:Vous verrez que tout ce qu'il fait est de créer un spécimen de
T
et de l'injecter dans le luminaire. En effet, la méthodeFreeze
est apparue comme un raccourci pratique pour cette opération même. Comme @ploeh l'a écrit dans son article présentant la méthode Freeze en 2010 :Compte tenu de cela, il n'est pas surprenant que le gel du même type
T
qu'une instance injectée donne la même instance.Maintenant, pour répondre à votre question :
Étant donné qu'un appareil représente le _contexte_ dans lequel un test s'exécute, vous _pouvez_ certainement avoir plusieurs tests qui partagent le même appareil ; cependant, cela se fait au prix d'un mélange de préoccupations multiples, voire conflictuelles.
Le livre xUnit Patterns le résume bien :
Cette "collision" est exactement ce qui se passe lorsqu'un test s'attend à ce qu'un objet de type
T
soit une instance spécifique, tandis qu'un autre test s'attendT
ce que faux objet .Étant donné que je ne peux pas penser à un scénario de test où il est logique que le même type
T
à la fois une simulation _et_ une instance concrète (bien que je sois heureux d'avoir tort), je vous suggère d'avoir ces les tests utilisent différents appareils, chacun configuré pour servir son scénario particulier.