Closed MihaiDaniel closed 2 months ago
The problem is the declaration .RuleFor
for the following inner class as a constant:
.RuleFor(mc => mc.MyInnerClass, new MyInnerClassFaker().Get());
The correct way to invoke the lambda upon each generaiton is to use the lambda overload; not the value/constant overload:
.RuleFor(mc => mc.MyInnerClass, f => new MyInnerClassFaker().Get());
^^^^^^
You need to make sure if you want something done on each generation instance, that you use lambdas .RuleFor( ... , f => f)
; not .RuleFor( ... , valueConstant)
.
And a working example:
void Main()
{
MyClassFaker myClassFaker = new();
MyClass class1 = myClassFaker.Get();
MyClass class2 = myClassFaker.Get();
class1.MyInnerClass.Id.Dump();
class2.MyInnerClass.Id.Dump();
}
public class MyClass
{
public int Id { get; set; }
public MyInnerClass MyInnerClass { get; set; }
}
public class MyInnerClass
{
public int Id { get; set; }
}
public class MyClassFaker
{
private Bogus.Faker<MyClass> faker = new();
public MyClassFaker()
{
faker
.RuleFor(mc => mc.Id, f => f.Random.Int())
.RuleFor(mc => mc.MyInnerClass, f => new MyInnerClassFaker().Get()); // Your bug was here.
}
public MyClass Get() { return faker.Generate(); }
}
public class MyInnerClassFaker
{
private Bogus.Faker<MyInnerClass> faker = new();
public MyInnerClassFaker()
{
faker.RuleFor(mc => mc.Id, f => f.Random.Int());
}
public MyInnerClass Get() { return faker.Generate(); }
}
1449290238
130403538
Hope that helps.
@bchavez Indeed that was the issue, thanks for the quick response!
Bogus NuGet Package
35.5.0
.NET Version
.NET 8
Visual Studio Version
17.8.3
What operating system are you using?
Windows
What locale are you using with Bogus?
en_US
Problem Description
I need to generate fake data that has inner objects but these inner generated objects seem to share the reference in any of the contained generated objects.
The problem arises when using a builder-like pattern to use bogus to build unique objects for testing purposes. I use inside a Faker rules another Faker to generate inner objects. Say I have a MyClass and a MyInnerClass that is a property inside MyClass. I would like to generate so that MyInnerClass has unique values for any MyClass generated, but what happens is that all MyClass share the same reference to the latest generated MyInnerClass
See code example. The assert should fail, but it passes.
LINQPad Example or Reproduction Steps
Expected Behavior
Fakers used inside other Rules of other fakers should not share references.
Actual Behavior
Fakers used inside Rules of other fakers shares the same reference to the newest generated object.
Known Workarounds
I haven't found a workaround yet, just to manually set the inner objects.
Could you help with a pull-request?
Yes