Библиотека С# для заполнения объекта случайными данными
Я хочу заполнить свой объект случайными данными (для целей тестирования), есть ли библиотека для этого?
Какой-то метод отражения, который пройдет через объектный граф и инициализирует примитивные свойства, такие как (string, int, DateTime и т.д.) (но делайте это глубоким путем, включая коллекции, дочерние объекты и т.д.)
Ответы
Ответ 1
NBuilder - очень хорошая библиотека fluent-API для генерации данных. Он использует правила, которые вы определяете и не являетесь "случайными" как таковыми. Однако вы можете рандомизировать входные данные API, чтобы удовлетворить ваши потребности.
Поскольку это все еще вызывает некоторое внимание, я думаю, что стоит упомянуть, что проект теперь доступен через NuGet (https://www.nuget.org/packages/NBuilder/), хотя он не был изменен с 2011 года.
Ответ 2
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)
{
}
}
}