J'essaie d'utiliser l'autofixture pour créer un objet mais il y a certaines propriétés que je veux toujours être par défaut (tandis que le reste pourrait être généré automatiquement). Cependant, chaque fois que je configure une personnalisation, elle est remplacée lorsque je crée avec des personnalisations.
void Main()
{
var fixture = new Fixture();
fixture.Customize<Person>(composer => composer.With(p => p.Name, "Ben"));
var person = fixture.Build<Person>()
.With(p => p.DateOfBirth, new DateTime(1900, 1, 1))
.Create();
/* RESULT OF person below
Name null
DateOfBirth 1/1/1900
StreetAddress StreetAddressafd6b86b-376a-4355-9a9c-fbae34731453
State State019e867b-ac5e-418f-805b-a64146bc06bc
*/
}
public class Person
{
public string Name { get; set;}
public DateTime DateOfBirth { get; set;}
public string StreetAddress { get; set;}
public string State { get; set;}
}
Les personnalisations des propriétés Name
et DateOfBirth
ne sont pas en conflit, donc je ne sais pas pourquoi Name finit par être nul. Je m'attendrais à ce que le nom soit Ben
.
Comment puis-je l'obtenir pour que les deux personnalisations soient appliquées (par exemple. Name = "Ben"
et DateOfBirth = 1/1/1900
)?
Comme @DavidOsborne l'a correctement souligné, le comportement que vous voyez est tel que conç .
Une meilleure approche consiste à organiser vos personnalisations dans des classes distinctes, puis à les activer selon les besoins d'un scénario de test spécifique.
Un objet de personnalisation implémente l'interface ICustomization
et son travail consiste à configurer l'objet Fixture
d'une manière spécifique. Voici un exemple:
public class AllPersonsAreNamedBen : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<Person>(composer =>
composer.With(p => p.Name, "Ben"));
}
}
public class AllPersonsAreBornIn1900 : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<Person>(composer =>
composer.With(p => p.DateOfBirth, new DateTime(1900, 1, 1)));
}
}
Vous pouvez activer une personnalisation sur un Fixture
spécifique en utilisant la méthode Customize
, par exemple:
fixture.Customize(new AllPersonsAreNamedBen());
ou:
fixture.Customize(new AllPersonsAreBornIn1900());
Vous pouvez également combiner plusieurs personnalisations en une nouvelle en utilisant la classe CompositeCustomization
:
public class AllPersonsAreNamedBenAndAreBornIn1900 : CompositeCustomization
{
public AllPersonsAreNamedBenAndAreBornIn1900()
: base(new AllPersonsAreNamedBen(),
new AllPersonsAreBornIn1900())
{
}
}
à quel point vous pouvez simplement dire:
fixture.Customize(new AllPersonsAreNamedBenAndAreBornIn1900());
Cependant, gardez à l'esprit que l'ordre dans lequel les personnalisations sont appliquées sur un Fixture
est important: le dernier gagne et peut potentiellement remplacer les précédents, comme l'a souligné @MarkSeemann dans les commentaires. Cela aussi est par conception .
Ainsi, pendant que vous pouvez combiner des personnalisations existantes qui fonctionnent sur différents types , dans ce cas particulier, puisque les deux personnalisations ciblent le même type, vous devrez créer une nouvelle personnalisation pour encapsuler tous les paramètres du type Person
combinés:
public class AllPersonsAreNamedBenAndAreBornIn1900 : CompositeCustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<Person>(composer =>
composer.With(p => p.Name, "Ben")
.With(p => p.DateOfBirth, new DateTime(1900, 1, 1)));
}
}
En règle générale, garder vos personnalisations petites et ciblées vous permet de les réutiliser dans différents tests, en les combinant pour un test spécifique scénarios.
On dirait que c'est par conception:
Notez que la chaîne de méthode Build est mieux comprise comme une personnalisation unique. Il contourne toutes les personnalisations sur l'instance
Fixture
. Au lieu de cela, il permet un contrôle à grain fin lors de la construction d'un spécimen spécifique. Cependant, dans la plupart des cas, l'ajout d'unICustomization
basé sur une convention est une option meilleure et plus flexible.
... à partir de la documentation de la méthode Build()
.
Je comprends que ce n'est probablement pas une réponse idéale. Cependant, la documentation fournit une indication sur la façon dont vous pourriez en arriver à un.