bchavez / Bogus

:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.
Other
8.66k stars 495 forks source link

Generation of an object inside the generation of an object #426

Closed mikwee closed 2 years ago

mikwee commented 2 years ago

Version Information

Software Version(s)
Bogus NuGet Package 34.0.2
.NET Core? 3.1.419
.NET Full Framework?
Windows OS? W10 Pro
Linux OS?
Visual Studio?

What locale are you using with Bogus?

Not really using a locale... I think

What's the problem?

I wanna generate a dummy object, that one of its properties is a generator of another dummy object. Is it possible?

What possible solutions have you considered?

I've considered this code:

public static Faker<School> FakeData {get;} =
            new Faker<School>()
                .RuleFor(p => p.ar[0], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[1], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[2], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[3], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[4], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[5], f => new Node<Student>(Student.FakeData.Generate()));

But instead of generating an object, it generated this error:

Unhandled exception. System.TypeInitializationException: The type initializer for 'ex1.School' threw an exception.
 ---> System.ArgumentException: Expression was not of the form 'x => x.Property or x => x.Field'.
   at Bogus.PropertyName.GetMemberName(Expression expression)
   at Bogus.PropertyName.For[T,TProp](Expression`1 expression)
   at Bogus.Faker`1.RuleFor[TProperty](Expression`1 property, Func`2 setter)
   at ex1.School..cctor() in D:\SWE (Let it be over!!!)\ex1\Program.cs:line 62
   --- End of inner exception stack trace ---
   at ex1.School.get_FakeData() in D:\SWE (Let it be over!!!)\ex1\Program.cs:line 61
   at ex1.Program.Main(String[] args) in D:\SWE (Let it be over!!!)\ex1\Program.cs:line 90

Do you have sample code to show what you're trying to do?

I hope you won't have to run this, but if you do, I can send you Unit4New.dll in some way.

using System;
using Unit4New;
using Bogus;

namespace ex1
{
    class Birth
    {
        private int day, month, year;

        public Birth(int day, int month, int year)
        {
            this.day = day;
            this.month = month;
            this.year = year;
        }

        public int Day { get => day; set => day = value; }
        public int Month { get => month; set => month = value; }
        public int Year { get => year; set => year = value; }

        public static Faker<Birth> FakeData {get;} =
            new Faker<Birth>()
                .RuleFor(p => p.day, f => f.Date.Past(18).Day)
                .RuleFor(p => p.month, f => f.Date.Past(18).Month)
                .RuleFor(p => p.year, f => f.Date.Past(18).Year);
    }

    class Student
    {
        private string name;

        private Birth birthDay;

        public Student(string name, Birth birthDay)
        {
            this.name = name;
            this.birthDay = birthDay;
        }

        public string Name { get => name; set => name = value; }
        public Birth BirthDay { get => birthDay; set => birthDay = value; }

        public static Faker<Student> FakeData {get;} =
            new Faker<Student>()
                .RuleFor(p => p.name, f => f.Name.FullName())
                .RuleFor(p => p.birthDay, f => Birth.FakeData.Generate());
    }

     class School
    {
        private Node<Student>[] ar = new Node<Student>[6];

        public School(Node<Student>[] ar)
        {
            this.ar = ar;
        }

        public Node<Student>[] Ar { get => ar; set => ar = value; }

        public static Faker<School> FakeData {get;} =
            new Faker<School>()
                .RuleFor(p => p.ar[0], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[1], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[2], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[3], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[4], f => new Node<Student>(Student.FakeData.Generate()))
                .RuleFor(p => p.ar[5], f => new Node<Student>(Student.FakeData.Generate()));
    }

    public static class Program
    {
        static Node<Student>[] studentsByMonth(School s)
        {
            Node<Student> node = s.Ar[0];
            Node<Student>[] res = new Node<Student>[12];
            for (int i = 0; i < 6; i++)
            {
                while(node != null)
                {
                    res[node.GetValue().BirthDay.Month] = node;
                    node = node.GetNext();
                }
            }
            return res;
        }

        public static void Main(string[] args)
        {
            School s = School.FakeData.Generate();
            Node<Student> node = s.Ar[0];
            for (int i = 0; i < 6; i++)
            {
                node = s.Ar[i];
                for (int i2 = 0; i2 < 30; i2++)
                {
                    node.SetNext(new Node<Student>(Student.FakeData.Generate()));
                    node = node.GetNext();
                }
            }
            Console.WriteLine(studentsByMonth(s));
        }
    }
}
Ikendiken commented 2 years ago

Why not new Faker<School>().RuleFor(p => p.ar, f => f.Make(6, f => new Node<Student>(Student.FakeData.Generate())));?

bchavez commented 2 years ago

Hello,

There is an example on the README page here:

There are two fakers Faker<User> and Faker<Order> and .RuleFor(u => u.Orders, f => testOrders.Generate(3).ToList()) that you'll want to review and understand.

Thank you for posting your code, but I can't run your code because it does not compile (nor does it run in LinqPad); so support for this problem is limited until you can provide working code in LinqPad (or a branch/fork with a failing unit test).