Closed altmank closed 1 year ago
Hello @altmank, thank you very much for the LinqPad example, it makes providing help much easier when we can communicate with concrete code and examples.
The first problem is,
RuleFor(t => t.Child, new PersonFaker().Generate());
You should always specify 2 lambdas for .RuleFor
. The .RuleFor
with one lambda is for using constant values (that never change). It's almost always a bug using the overload with one lambda as above.
Rather, you should write rules like the following below:
RuleFor(t => t.Child, f => new PersonFaker().Generate());
The second problem is a misconception on how to flow state between Faker<T1>
and Faker<T2>
. The important thing to know about Faker<T>
is that they are completely independent and isolated from one another. Faker<T1>
knows nothing about Faker<T2>
unless you carry the state along between them and explicitly use the state your asking for.
The reason why your PersonWrapperFaker
is always .Child = null
is that the ruleset for "young" is defined in Person
, not PersonWrapperFaker
. In simpler terms,
void Main()
{
var f = new FooFaker();
f.Generate("myrules").Dump();
f.Generate("non-existing-ruleset").Dump(); // does nothing because the rulset is not defined
}
public class Foo
{
public string Message {get;set;}
}
public class FooFaker : Faker<Foo>
{
public FooFaker()
{
RuleSet("myrules", rule =>
{
rule.RuleFor(f => f.Message, f => "This 'myrules' ruleset exists");
});
}
}
Finally, expanding this further,
void Main()
{
var parentFaker = new ParentFaker();
// I want all generation to happen among both the parent and all
// child faker objects to use the specified ruleset of "young"
parentFaker.WithChildRuleset("young").Generate().Dump("With parent: young");
parentFaker.WithChildRuleset("").Generate().Dump("With parent: none|default");
var personFaker = new PersonFaker();
personFaker.Generate("young").Dump("Directly on child faker object");
}
public class Parent
{
public Person Child { get; set; }
}
public class Person
{
public bool IsOld { get; set; }
}
public class ParentFaker : Faker<Parent>
{
public ParentFaker()
{
RuleFor(t => t.Child, f => new PersonFaker().Generate(this.childRuleset));
}
string childRuleset = ""; // default child rulset
public ParentFaker WithChildRuleset(string ruleset){
this.childRuleset = ruleset;
return this;
}
}
public class PersonFaker : Faker<Person>
{
public PersonFaker()
{
//default "" ruleset
RuleFor(x => x.IsOld, f => true);
RuleSet("young", rule =>
{
rule.RuleFor(x => x.IsOld, f => false);
});
}
}
Yields the following:
Hope that helps.
Thanks,
Brian Chavez
I'm trying to create objects where objects higher in a hierarchy may have to have properties generated by other faker classes. I want to support having the ruleset passed to the top level object propagate that ruleset down to child faker instances used in property faking.
I can't seem to get this to work and its behavior seems like a bug to me. Can you please take a quick look and evaluate if I'm approaching this wrong or if there is a defect here in ruleset functionality?
Example Linqpad script: