使用Generics获取随机数据

我们的unit testing之一是使用随机数据填充业务对象中的属性。

这些属性具有不同的内在类型,因此我们希望使用generics的function来返回您传入的类型的数据。有些内容如下:

public static T GetData() 

你会怎么去接近这个? 低级别界面会起作用吗? (IConvertible)

这取决于您想要随机化的数据,因为您要使用的方式算法完全不同,具体取决于类型。

例如:

 // Random int Random r = new Random(); return r.Next(); // Random Guid return Guid.NewGuid(); ... 

因此,这显然使得generics的使用在用户端是一个很好的简化,但它对你编写类的方式没有任何价值。 您可以使用switch子句或字典(如Jon Skeet建议):

 switch(typeof(T)) { case System.Int32: Random r = new Random(); return (T)r.Next(); case System.Guid: return (T)Guid.NewGuid(); ... 

然后你将按预期使用该类:

 RandomGenerator.GetData(); ... 

您可以保留“易于使用”的GetData接口,但内部有一个Dictionary ,其中每个值都是相关类型的Func 。 然后GetData将具有如下实现:

 public static T GetData() { object factory; if (!factories.TryGet(typeof(T), out factory)) { throw new ArgumentException("No factory for type " + typeof(T).Name); } Func factoryFunc = (Func) factory; return factoryFunc(); } 

然后,您可以在静态初始化程序中设置工厂字典,并为要创建的每种类型的随机数据指定一个委托。 在某些情况下,您可以使用简单的lambda表达式(例如,对于整数),在某些情况下,委托可以指向执行更多工作的方法(例如,对于字符串)。

顺便说一下,您可能希望将我的StaticRandom类用于线程安全的RNG。

一般来说,我会避免编写随机unit testing,因为这不是unit testing的目的。 在编写unit testing时,您确实需要手动生成数据以确保覆盖类/程序中的所有路径,并且通常在测试中对此数据进行硬编码,以便重新运行测试。

所以我猜你真的在编写冒烟测试,看看你的软件对大数据集的表现如何。 在这里,我认为你应该像其他人已经建议的那样为你的每个业务对象类型实现一个特定的生成器 – 以确保数据与你在生产中的期望相似(例如,如果ID是顺序的,那么生成顺序和不是随机的)。

我会使用AutoPoco生成测试所需的数据。