How to use AutoFixture to build with customized properties while keeping type customizations?

后端 未结 3 1735
深忆病人
深忆病人 2021-02-13 00:19

I am trying to use autofixture to create an object but there are certain properties that I want to always be defaulted (while the rest could be auto generated). However, wheneve

3条回答
  •  我在风中等你
    2021-02-13 00:46

    As @DavidOsborne correctly pointed out, the behavior you are seeing is as designed.

    A better approach is to organize your customizations in separate classes and then enable them as needed by a specific test scenario.

    A customization object implements the ICustomization interface and its job is to configure the Fixture object in a specific way. Here's an example:

    public class AllPersonsAreNamedBen : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customize(composer =>
                composer.With(p => p.Name, "Ben"));
        }
    }
    
    public class AllPersonsAreBornIn1900 : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customize(composer =>
                composer.With(p => p.DateOfBirth, new DateTime(1900, 1, 1)));
        }
    }
    

    You can enable a customization on a specific Fixture by using the Customize method, for example:

    fixture.Customize(new AllPersonsAreNamedBen());
    

    or:

    fixture.Customize(new AllPersonsAreBornIn1900());
    

    You can also combine multiple customizations into a new one by using the CompositeCustomization class:

    public class AllPersonsAreNamedBenAndAreBornIn1900 : CompositeCustomization
    {
        public AllPersonsAreNamedBenAndAreBornIn1900()
            : base(new AllPersonsAreNamedBen(),
                   new AllPersonsAreBornIn1900())
        {
        }
    }
    

    at which point you can simply say:

    fixture.Customize(new AllPersonsAreNamedBenAndAreBornIn1900());
    

    However, keep in mind that the order in which the customizations are applied on a Fixture matters: the last one wins and can potentially override the previous ones, as @MarkSeemann pointed out in the comments. This, too, is by design.

    So, while you can combine existing customizations that work on different types, in this particular case, since both customizations target the same type, you'll have to create a new customization to encapsulate all the settings for the Person type combined:

    public class AllPersonsAreNamedBenAndAreBornIn1900 : CompositeCustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customize(composer =>
                composer.With(p => p.Name, "Ben")
                        .With(p => p.DateOfBirth, new DateTime(1900, 1, 1)));
        }
    }
    

    As a general rule, keeping your customizations small and focused enables you to reuse them in different tests, combining them for specific test scenarios.

提交回复
热议问题