nickdodd79 / AutoBogus

A C# library complementing the Bogus generator by adding auto creation and population capabilities.
MIT License
431 stars 50 forks source link

Fixed AutoFaker<T>.Generate populating the properties of a generated object twice #53

Closed logiclrd closed 3 years ago

logiclrd commented 3 years ago

When making a quick test app to prove the use of WithFakerHub, I discovered a bug: The AutoFaker<T> class, when generating instances of T, initializes them with bogus data twice.

This is because in the Generate method, it sets up a CreateAction, and that CreateAction, whose job it is to produce an actual instance of T, does so by calling AutoGeneratorFactory.GetGenerator(context).Generate(context). The resulting T has its members initialized already -- but, a separate FinalizeAction is also registered, which overwrites whatever is already in the object, and the underlying Faker calls this via its PopulateInternal method before returning:

         // Faker[T].cs line 458:
         var instance = createRule(this.FakerHub);

         PopulateInternal(instance, cleanRules);

         return instance;

When the non-generic AutoFaker's Generate<TType> method is being used, it does not use Faker.Generate<TType> at all; instead, it goes directly to AutoBogus's AutoBinder and calls CreateInstance<TType> followed by PopulateInstance<TType>. This CreateInstance<TType> call does not fill the object with bogus data, so it only gets populated once.

The Binder.PopulateInstance<TType> is the same action that the FinalizeAction in AutoBogus<T> takes to populate the object, so I believe the correct thing for the CreateAction to be doing is Binder.CreateInstance<TType>. This makes the AutoFaker<T>.Generate flow parallel the actions that TypeGenerator takes when AutoFaker.Generate<TType> is used.

This PR adds a unit test that fails when the erroneous behaviour occurs, and makes this small change to the CreateAction used by AutoFaker<T> to fix the failing test.

nickdodd79 commented 3 years ago

Hey @logiclrd

Great catch and thanks for putting the fix in.

Nick.