nickdodd79 / AutoBogus

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

How to exclude navigation properties in generating of enties #17

Closed cryptic224 closed 5 years ago

cryptic224 commented 5 years ago

How do I generate objects leaving out their navigation properties or properties that point to other objects? I tried configuring with builder.RecursiveDepth(0) but that did not work. Is it anything along those lines or any other way to configure that?

nickdodd79 commented 5 years ago

Hi @cryptic224

At the moment AutoBogus executes on the basis that all properties need to be populated. I can certainly look to add a configuration setting that allows properties to be set as ignored.

In the meantime, a workaround would be:

var faker = new AutoFaker<MyClass>()
  .RuleFor(c => c.PropertyToIgnore, default);

faker.Generate();

Any properties with a RuleFor setup are ignore by AutoBogus on the assumption that these will be assigned to manually rather than auto generated. Doing the above and assigning the default values for the property type, means the auto generate will skip you property.

Nick.

cryptic224 commented 5 years ago

Alright @nickdodd79 , thank you!

gatkin commented 5 years ago

If the navigation property is a collection, I found I needed to use CustomInstantiator to make data geneartion work, e.g.

var faker = new AutoFaker<MyClass>()
    .CustomInstantiator(f => new MyClass());
nickdodd79 commented 5 years ago

Hi,

I have just released v2.4.0 that now contains a WithSkip() configuration handler. It accepts an expression to a type member that should be skipped during a generate request. I think we should be able to elaborate on this further to allow specific object paths (as a string) to be skipped.

Nick.

nickdodd79 commented 5 years ago

Closing as this seems to be resolved.

gtrabbit commented 10 months ago

My apologies for commenting on a closed issue, but the WithSkip() configuration would require that every path on every entity were individually configured. If you are looking to write something that will disable generation of virtual members across the board, that won't do. If anyone is interested, I was able to achieve that by building a small wrapper around the default AutoBinder that excludes any virtual properties on the current instance from being populated, and otherwise delegates everything else to the default implementation. This relies on the knowledge of how the members parameter is used by PopulateInstance, but since that method is part of the IAutoBinder interface, I figure that's fair game. The code is below:

public class NoVirtualMemberAutoBinder : IAutoBinder
{
  private readonly IAutoBinder _binder;
  public NoVirtualMemberAutoBinder(IAutoBinder binder)
  {
      _binder = binder;
  }

  public TType CreateInstance<TType>(AutoGenerateContext context)
  {
      return _binder.CreateInstance<TType>(context);
  }

  public Dictionary<string, MemberInfo> GetMembers(Type t)
  {
      return _binder.GetMembers(t);
  }

  public void PopulateInstance<TType>(object instance, AutoGenerateContext context, IEnumerable<MemberInfo> members = null)
  {
      if (instance is not null)
      {
          var instanceType = instance.GetType();
          var nonVirtualProps = instanceType.GetProperties().Where(p => !p.GetMethod.IsVirtual);
          _binder.PopulateInstance<TType>(instance, context, nonVirtualProps);
      }
      else
      {
          _binder.PopulateInstance<TType>(instance, context, members);
      }
  }
}

You can set this up as usual: AutoFaker.Configure(builder => { builder.WithBinder(new NoVirtualMemberAutoBinder(new AutoBinder())); });