使用泛型获取随机数据

本文关键字:随机 数据 获取 泛型 | 更新日期: 2023-09-27 17:47:21

我们的单元测试之一是用随机数据填充业务对象中的属性。

这些属性属于不同的内部类型,因此我们希望使用泛型的强大功能来返回您传入的类型的数据。大致如下:

public static T GetData<T>()

你会如何解决这个问题?低级接口会起作用吗?(可逆)

使用泛型获取随机数据

你可以保留你在那里的"易于使用"的GetData接口,但内部有一个字典<Type,对象>其中每个值都是相关类型的Func。然后,GetData 将有一个实现,例如:

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

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

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

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

所以我想你真的在写烟雾测试,看看你的软件在大数据集上的表现。在这里,我认为您应该为每个业务对象类型实现一个特定的生成器,正如其他人已经建议的那样 - 以确保数据与您在生产中的预期相当相似(例如,如果 ID 是顺序的,则生成它们是顺序的而不是随机的)。

这取决于您要随机化的数据,因为您想要使用的方式算法因类型而异。

例如:

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

因此,这显然使泛型的使用成为用户端的一个很好的例证,但它不会为您编写类的方式增加任何价值。你可以使用开关子句或字典(如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<Guid>();
...

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