Search code examples
c#.netautofixturensubstitute

Example of how to use AutoFixture with NSubstitute


I use NSubstitute a lot. And I love it.

I am just looking into AutoFixture. It seems great!

I have seen AutoFixture for NSubstitute and seen a few examples in Moq on how to use this feature.

But I can't seem to translate it into NSubstitute.

I tried this:

var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());  
var addDest = Substitute.For<IPerson>();

Using:

public interface IPersonEntity
{    
   int ID { get; set; }
   string FirstName { get; set;}
   string LastName { get; set;}
   DateTime DateOfBirth { get; set; }
   char Gender { get; set; }    
}

And I get an object, but none of the properties are populated (kind of the point of AutoFixture).

I also tried:

var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
var result = fixture.Create<IPersonEntity>();

That also gave me an object with no populated properties. (Note if I do the above with a PersonEntity class, then the properties are all populated.)

I am sure that there is a way to make this work, but I can't seem to find it.

So, given my IPersonEntity interface above, does anyone know how to use AutoFixture and NSubstitute to give me a populated IPersonEntity object?


Solution

  • Instead of customizing the Fixture instance with the AutoNSubstituteCustomization you may use the customization below:

    var fixture = new Fixture().Customize(
        new AutoPopulatedNSubstitutePropertiesCustomization());
    
    var result = fixture.Create<IPersonEntity>();
    // -> All properties should be populated now.
    

    The AutoPopulatedNSubstitutePropertiesCustomization is defined as:

    internal class AutoPopulatedNSubstitutePropertiesCustomization
        : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.ResidueCollectors.Add(
                new Postprocessor(
                    new NSubstituteBuilder(
                        new MethodInvoker(
                            new NSubstituteMethodQuery())),
                    new AutoPropertiesCommand(
                        new PropertiesOnlySpecification())));
        }
    
        private class PropertiesOnlySpecification : IRequestSpecification
        {
            public bool IsSatisfiedBy(object request)
            {
                return request is PropertyInfo;
            }
        }
    }
    

    The difference with the AutoNSubstituteCustomization is that the above customization is also decorated with a Postprocessor instance to automatically set values for all the public properties of the requested type.

    References:

    The above solution is inspired by the following blog articles by Mark Seemann: