C#库用随机数据填充对象

时间:2011-07-08 13:56:59

标签: c#

我想用随机数据填充我的对象(用于测试目的),有没有库可以做到?

某种反射方法,它将遍历对象图并初始化原始属性,如(string,int,DateTime等)(但深入地做,包括集合,子对象等)

12 个答案:

答案 0 :(得分:33)

Bogus

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 ,则可以使用FakeItEasyGitHub),这是一个免费的开源.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)
            {

            }
        }
    }