C# 使用泛型获取随机数据

C# 使用泛型获取随机数据,c#,unit-testing,generics,C#,Unit Testing,Generics,我们的单元测试之一是用随机数据填充业务对象中的属性 这些属性具有不同的内在类型,因此我们希望使用泛型的功能来返回您传入的类型的数据。大致如下: public static T GetData<T>() publicstatict GetData() 你将如何着手处理这个问题?低级别的接口可以工作吗?(IConvertible)您可以保留现有的“易于使用”的GetData接口,但内部有一个字典,其中每个值都是相关类型的Func。然后,GetData将有一个实现,例如: public

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

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

public static T GetData<T>()
publicstatict GetData()
你将如何着手处理这个问题?低级别的接口可以工作吗?(IConvertible)

您可以保留现有的“易于使用”的GetData接口,但内部有一个字典,其中每个值都是相关类型的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();
}
publicstatict GetData()
{
对象工厂;
if(!Factorys.TryGet(类型(T),出厂))
{
抛出新的ArgumentException(“类型无工厂”+typeof(T).Name);
}
Func factoryFunc=(Func)工厂;
返回factoryFunc();
}
然后在静态初始值设定项中设置factory字典,每个要创建的随机数据类型都有一个委托。在某些情况下,您可以使用一个简单的lambda表达式(例如,对于整数),在某些情况下,委托可以指向一个做更多工作的方法(例如,对于字符串)


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

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

例如:

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

// Random Guid
return Guid.NewGuid();

...
因此,这显然使泛型的使用在用户端成为一种很好的符号化,但它并没有为您编写类的方式增加任何价值。您可以使用switch子句或字典(如Jon Skeet建议的):

然后,您将按照预期使用该类:

RandomGenerator.GetData<Guid>();
...
RandomGenerator.GetData();
...

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


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

我会用它来生成测试所需的数据。

谢谢,我会试一试并发回我的结果。我只是问一个问题,为什么你首先要将factory声明为object而不是Func?因为字典被声明为dictionary,而且必须是,因为您无法表示字典中的值的类型取决于键:((实际上,您可以将其设置为字典,但这并不重要。)工厂查找可能会通过实现递归搜索而有所改进。如果没有找到类型t的工厂,请尝试获取类型of(t)的工厂.BaseType等。但我不确定如果您对基类型使用此GetData方法是否真的有用…为了将r.Next()强制转换为类型T,将不会从中继承什么?我假设强制转换将在运行时解决,但我没有尝试,如果没有,您可以双重强制转换(T)(对象)…这非常有效,因为我正在寻找的解决方案非常简单。感谢您何时可以在typeC上执行切换大小写?6.0新的表达式nameof(T)可以用于返回类型名称。使用nameof(T)更改switch语句和使用nameof(Int32)更改大小写标签等都可以@sklivz请编辑答案:)
RandomGenerator.GetData<Guid>();
...