Подтвердить что ты не робот

Библиотека С# для заполнения объекта случайными данными

Я хочу заполнить свой объект случайными данными (для целей тестирования), есть ли библиотека для этого?

Какой-то метод отражения, который пройдет через объектный граф и инициализирует примитивные свойства, такие как (string, int, DateTime и т.д.) (но делайте это глубоким путем, включая коллекции, дочерние объекты и т.д.)

4b9b3361

Ответ 1

NBuilder - очень хорошая библиотека fluent-API для генерации данных. Он использует правила, которые вы определяете и не являетесь "случайными" как таковыми. Однако вы можете рандомизировать входные данные API, чтобы удовлетворить ваши потребности.

Поскольку это все еще вызывает некоторое внимание, я думаю, что стоит упомянуть, что проект теперь доступен через NuGet (https://www.nuget.org/packages/NBuilder/), хотя он не был изменен с 2011 года.

Ответ 2

Bogus

Bogus - простой и разумный генератор фальшивых данных для С# и .NET. Порт С# faker.js и вдохновлен синтаксисом сахара FluentValidation. Поддерживает .NET Core.

Настройка

public enum Gender
{
   Male,
   Female
}

var userIds = 0;

var testUsers = new Faker<User>()
    //Optional: Call for objects that have complex initialization
    .CustomInstantiator(f => new User(userIds++, f.Random.Replace("###-##-####")))

    //Basic rules using built-in generators
    .RuleFor(u => u.FirstName, f => f.Name.FirstName())
    .RuleFor(u => u.LastName, f => f.Name.LastName())
    .RuleFor(u => u.Avatar, f => f.Internet.Avatar())
    .RuleFor(u => u.UserName, (f, u) => f.Internet.UserName(u.FirstName, u.LastName))
    .RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName))
    //Use an enum outside scope.
    .RuleFor(u => u.Gender, f => f.PickRandom<Gender>())
    //Use a method outside scope.
    .RuleFor(u => u.CartId, f => Guid.NewGuid());

Создать

var user = testUsers.Generate();
Console.WriteLine(user.DumpAsJson());

/* OUTPUT:
{
  "Id": 0,
  "FirstName": "Audrey",
  "LastName": "Spencer",
  "FullName": "Audrey Spencer",
  "UserName": "Audrey_Spencer72",
  "Email": "[email protected]",
  "Avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/itstotallyamy/128.jpg",
  "Gender": 0,
  "CartId": "863f9462-5b88-471f-b833-991d68db8c93", ....

Без свободного синтаксиса

  public void Without_Fluent_Syntax()
  {
      var random = new Bogus.Randomizer();
      var lorem = new Bogus.DataSets.Lorem();
      var o = new Order()
          {
              OrderId = random.Number(1, 100),
              Item = lorem.Sentence(),
              Quantity = random.Number(1, 10)
          };
      o.Dump();
  }
  /* OUTPUT:
  {
    "OrderId": 61,
    "Item": "vel est ipsa",
    "Quantity": 7
  } */

Ответ 3

Я попробовал AutoFixture (http://autofixture.codeplex.com/), и это сработало для меня очень хорошо. Он может легко генерировать объект с глубокой иерархией дочерних элементов в одной строке кода.

Ответ 4

Недавно я работал над тем, что было похоже на то, что вы описали (возможно, это было сделано раньше, но это казалось забавным проектом, чтобы попробовать). Это все еще работа, но я думаю, что она отражает все функции, которые вы упомянули. Пакет Nuget можно найти здесь:

https://www.nuget.org/packages/randomtestvalues

И репозиторий здесь: https://github.com/RasicN/random-test-values

Надеюсь, вам понравится.

Пример кода:

var randomMyClass = RandomValue.Object<MyClass>();

Ответ 5

AutoPoco имеет некоторые из этих функций, он не делает этого с отражением, вы говорите, какой тип данных заполнять. Поэтому, если вы пишете модульные тесты, вы можете сделать это в методе [Setup] или [TestInitialize].

Ответ 6

NBuilder довольно приятный.

Я считаю, что он также использует отражение.

Ответ 7

Redgate создает инструмент SQL Data Generator. Если вы хотите использовать базу данных в качестве семени для объектов тестирования, я думаю, вы обнаружите, что это довольно гибкий инструмент.

Ответ 8

PM> Install-Package NBuilder

note: сам класс EducationInformation имеет множество свойств строки

var rootObject = new RootObject()
            {
                EducationInformation = Builder<EducationInformation>.CreateNew().Build(),
                PersonalInformation = Builder<PersonalInformation>.CreateNew().Build(),
                PositionsInformation = Builder<PositionsInformation>.CreateNew().Build()                    
            };

образец окончательного вывода JSON: все с именем свойства и числом

"graduateDegree":"graduateDegree1","academicDiscipline":"academicDiscipline1"

note: я не знаю, почему использование следующей команды возвращает null для всех внутренних классов

RootObject rootObject = Builder<RootObject>.CreateNew().Build() 

Ответ 9

Если вы используете .NET, вы можете использовать FakeItEasy (GitHub), свободная и открытая .NET-фрейм-платформа .NET.

И он совместим с .NET Core.

Ответ 10

Так как некоторые библиотеки либо немного устарели, либо больше не разрабатываются, я создал свою собственную библиотеку Oxygenize, что позволяет заполнять классы произвольными или настроенными данными.

Ответ 11

RandomPOCOGenerator - это простой инструмент на основе отражения, предназначенный для создания и заполнения объектов со случайными значениями

[TestMethod]
public void GenerateTest()
{
   RPGenerator gen = new RPGenerator();
   int maxRecursionLevel = 4;

   var intRes = gen.Generate<int>(maxRecursionLevel);            
   var stringArrayRes = gen.Generate<string[]>(maxRecursionLevel);
   var charArrayRes = gen.Generate<char[]>(maxRecursionLevel);
   var pocoRes = gen.Generate<SamplePocoClass>(maxRecursionLevel);
   var structRes = gen.Generate<SampleStruct>(maxRecursionLevel);
   var pocoArray = gen.Generate<SamplePocoClass[]>(maxRecursionLevel);
   var listRes = gen.Generate<List<SamplePocoClass>>(maxRecursionLevel);
   var dictRes = gen.Generate<Dictionary<string, List<List<SamplePocoClass>>>>(maxRecursionLevel);
   var parameterlessList = gen.Generate<List<Tuple<string, int>>>(maxRecursionLevel);

   // Non-generic Generate
   var stringArrayRes = gen.Generate(typeof(string[]), maxRecursionLevel);
   var pocoRes = gen.Generate(typeof(SamplePocoClass), maxRecursionLevel);
   var structRes = gen.Generate(typeof(SampleStruct), maxRecursionLevel);

   Trace.WriteLine("-------------- TEST Results ------------------------");
   Trace.WriteLine(string.Format("TotalCountOfGeneratedObjects {0}", gen.TotalCountOfGeneratedObjects));
   Trace.WriteLine(string.Format("Generating errors            {0}", gen.Errors.Count));
}

Ответ 12

Легко и чисто:

public static void populateObject( object o)
    {
        Random r = new Random ();
        FieldInfo[] propertyInfo = o.GetType().GetFields();
        for (int i = 0; i < propertyInfo.Length; i++)
        {
            FieldInfo info = propertyInfo[i];

            string strt = info.FieldType.Name;
            Type t = info.FieldType;
            try
            {
                dynamic value = null;

                if (t == typeof(string) || t == typeof(String))
                {
                    value = "asdf";
                }
                else if (t == typeof(Int16) || t == typeof(Int32) || t == typeof(Int64))
                {
                    value = (Int16)r.Next(999);
                    info.SetValue(o, value);
                }
                else if (t == typeof(Int16?))
                {
                    Int16? v = (Int16)r.Next(999);
                    info.SetValue(o, v);
                }
                else if (t == typeof(Int32?))
                {
                    Int32? v = (Int32)r.Next(999);
                    info.SetValue(o, v);
                }
                else if (t == typeof(Int64?))
                {
                    Int64? v = (Int64)r.Next(999);
                    info.SetValue(o, v);
                }
                else if (t == typeof(DateTime) || t == typeof(DateTime?))
                {
                    value = DateTime.Now;
                    info.SetValue(o, value);
                }
                else if (t == typeof(double) || t == typeof(float) || t == typeof(Double))
                {
                    value = 17.2;
                    info.SetValue(o, value);
                }
                else if (t == typeof(char) || t == typeof(Char))
                {
                    value = 'a';
                    info.SetValue(o, value);
                }
                else
                {
                    //throw new NotImplementedException ("Tipo não implementado :" + t.ToString () );
                    object temp = info.GetValue(o);
                    if (temp == null)
                    {
                        temp = Activator.CreateInstance(t);
                        info.SetValue(o, temp);
                    }
                    populateObject(temp);
                }
            }
            catch (Exception ex)
            {

            }
        }
    }