我想用随机数据填充我的对象(用于测试目的),有没有库可以做到?
某种反射方法,它将遍历对象图并初始化原始属性,如(string,int,DateTime等)(但深入地做,包括集合,子对象等)
答案 0 :(得分:33)
Bogus是一个简单而健全的C#和.NET假数据生成器。 faker.js的C#端口,受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": "Audrey82@gmail.com",
"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
} */
答案 1 :(得分:26)
NBuilder是一个非常好的用于生成数据的流畅API库。它使用您定义的规则,而不是“随机”本身。但是,您可以将输入随机化到API,以满足您的需求。
由于这仍然引起了一些关注,我认为值得一提的是该项目现在也可以通过NuGet(https://www.nuget.org/packages/NBuilder/)获得,尽管自2011年以来它没有被修改过。
答案 2 :(得分:10)
我尝试过AutoFixture(https://github.com/AutoFixture/AutoFixture),它对我很有帮助。 它可以在一行代码中轻松生成具有深层次子层次的对象。
答案 3 :(得分:7)
我最近一直在研究一个与你所描述的完全相同的东西(也许它之前已经完成过,但这似乎是一个有趣的项目)。它仍在进行中,但我认为它捕获了您提到的所有功能。你可以在这里找到Nuget包:
https://www.nuget.org/packages/randomtestvalues
此处的存储库:https://github.com/RasicN/random-test-values
我希望你喜欢它。
示例代码:
var randomMyClass = RandomValue.Object<MyClass>();
答案 4 :(得分:4)
AutoPoco有一些功能,它没有用反射做,你告诉它填充什么类型的数据。因此,如果您正在编写单元测试,则可以使用[Setup]
或[TestInitialize]
方法进行单元测试。
答案 5 :(得分:4)
NBuilder非常好。
我相信它也会使用反射。
答案 6 :(得分:2)
Redgate制作了一个名为SQL Data Generator的工具。如果您愿意将数据库用作测试对象的种子,我想您会发现它是一个非常灵活的工具。
答案 7 :(得分:1)
PM> Install-Package NBuilder
注意: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"
注意:我不知道为什么使用以下命令会为所有内部类返回null
RootObject rootObject = Builder<RootObject>.CreateNew().Build()
答案 8 :(得分:1)
如果您使用 .NET ,则可以使用FakeItEasy(GitHub),这是一个免费的开源.NET动态虚假框架。
它与.NET Core兼容。
答案 9 :(得分:0)
由于某些库有点过时或不再处于开发阶段,我已经创建了自己的库Oxygenize,这使您可以使用随机数据或自定义数据填充类。
答案 10 :(得分:0)
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));
}
答案 11 :(得分:-2)
简单易懂:
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)
{
}
}
}