soenneker / soenneker.utils.autobogus

The .NET Autogenerator
https://soenneker.com
MIT License
39 stars 4 forks source link

AutoFaker<T> not respecting custom RuleFor for protected properties linked to public properties #341

Closed Ephaltes closed 1 month ago

Ephaltes commented 1 month ago

Hello,

I am encountering an issue where AutoFaker does not work as expected when dealing with a protected property that is linked to a public property.

Actual behaviour:

AutoFaker<T>.RuleFor(data => data.MyList, new List())

The List still gets initialized with 1 item, despite the rule specifying an empty list.

Expected behaviour:

AutoFaker<T>.RuleFor(data => data.MyList, new List())

The List should be initialized as empty.

Use Case:

I have a IReadOnlyCollection exposed as a public property, and I need to modify the underlying list internally. To achieve this, I use a protected ICollection for internal access:

public IReadOnlyCollection<T> PublicList { get; private set; } protected ICollection<T> InternalList => (ICollection<T>)PublicList;

The purpose of having this InternalList is to pass it to another module (e.g., a Mapper) that modifies the list. However, since the Mapper is in a different assembly, the internal access modifier cannot be used. Additionally, casting the IReadOnlyCollection to ICollection within the Mapper throws an error.

When I attempt to initialize the list with specific items using RuleFor, the behavior is not as expected. Even after applying a rule to initialize the list with 4 items, the list ends up with 5 items: the 4 I specified, plus 1 additional item generated by AutoBogus.

Please refer to the sample project and screenshot for further details. 2024-10-15 19_08_38-Window AutobogusTest.zip

soenneker commented 1 month ago

@Ephaltes It looks like the protected member is being set by AutoFaker, which then updates the public collection. This causes the public collection to follow the rule you’ve set, but the protected member ends up changing it again.

You could resolve this by setting RecursiveDepth to 0 to prevent automatic generation of members, or by adjusting the ReflectionCacheOptions flags to ignore protected members. Another option would be using an AutoFakerOverride to control the behavior.