我想模拟对象数据,而不是对象本身。换句话说,我想生成 n 个对象的集合并将其传递给一个生成随机数据字符串和数字的函数。有什么可以做的吗?将其视为对象数据的Lorem Ipsum。数字范围等方面的限制不是必需的,但会是一个额外的好处。
当我读到你的问题时,我首先想到的是 QuickCheck,一个 Haskell 的测试工具。在 QuickCheck 中,您指定函数应具有的属性(不变量),并且可以指定输入的有效范围(加上更多功能),QuickCheck 将生成一堆随机输入数据并将其扔到您的函数中并检查也请参阅如果输出符合规格。经过一番探索,我发现它有一个 F# 端口,因此 QuickCheck 存在于 .net 世界中:
还有一个 MS 研究项目 Pex 可能与您的想法很接近:
http://research.microsoft.com/en-us/projects/Pex/
“...Pex 会发现方法的有趣输入输出值,您可以将其保存为具有高代码覆盖率的小型测试套件。Microsoft Pex 是一个用于测试 .NET Framework 应用程序的 Visual Studio 插件。”
我以前没有使用过它,但看起来它对于生成执行函数的任何和所有分支的边缘情况数据很有帮助。它实际上分析了一个函数,而不是仅仅向它扔真正随机的东西。
似乎还有 Ruby
Faker
gem 的 .NET 端口,它被大量用于在 Ruby 中操纵虚假数据对象。我还没用过,但可能值得研究一下:
令我惊讶的是,还没有人提到AutoFixture:
[TestMethod]
public void IntroductoryTest()
{
// Fixture setup
Fixture fixture = new Fixture();
int expectedNumber = fixture.CreateAnonymous<int>();
MyClass sut = fixture.CreateAnonymous<MyClass>();
// Exercise system
int result = sut.Echo(expectedNumber);
// Verify outcome
Assert.AreEqual<int>(expectedNumber, result, "Echo");
// Teardown
}
您可以设置一个
ObjectRandomizer
类,该类采用对象数组,使用反射来检查对象中的私有成员,然后使用反射为该成员设置随机值。仅当您不关心每个对象的随机数据是什么样子时,这才有效。
或者,您可以为每个数据对象构建一组类,为它们生成随机数据。如果您不想在实际程序集中包含随机生成方法,这可能会很有效。例如,如果您有一个
Person
类,则测试程序集中也可以有一个 PersonRandomizer
类。在您的测试类中(或在 Randomizer
类中),您可以使用反射来查找类型 PersonRandomizer
,如果存在,则调用 PersonRandomizer.Randomize(Person p)
。
如果您同意 yahya 的建议,我建议为支持随机化的对象创建一个接口
IRandomizable
或使用您可以在运行时检测到的新属性 Randomizable
标记它们。
对于我的测试,我只是向我创建的所有类添加一个方法来执行此操作,并将其称为随机化。每个类都知道该类的对象的合法数据应该是什么样子。创建对象后,只需调用其 randomize 方法即可用随机模拟数据填充它。您还可以添加专门的方法来根据约束生成随机数据字符串或数字,并且这些专门的方法可以在所有类之间共享。