我有现有的测试代码,需要扩展。
为了减少代码重复,我想尽可能保持通用性,这是当前代码的简化片段:
public class FilterValueOne { }
[TestClass]
public class TestClass
{
[TestMethod]
public void FilterValueOne_TestMethod()
{
ManipulateData(BuildFilter());
}
private void ManipulateData(FilterValueOne filter)
{
// Do some stuff with filter
}
private FilterValueOne BuildFilter()
{
var filter = new FilterValueOne();
// Initialize filter data members here...
return filter;
}
}
这有效,但仅限于“ FilterValueOne”类型。
我想扩展它,并通过实现泛型类型参数使其更通用。
下面的代码段是我想要的:
// Enum will expand as the app grows
public enum TypeEnum
{
ValueOne,
ValueTwo,
ValueThree
}
// More classes will be added as the app grows
public class FilterValueOne { }
public class FilterValueTwo { }
public class FilterValueThree { }
[TestClass]
public class TestClassGeneric
{
// _filter to be used as the generic type argument
private object _filter;
// Constructor
public TestClassGeneric(TypeEnum val)
{
switch (val)
{
case TypeEnum.ValueOne:
_filter = GetTestObject<FilterValueOne>();
break;
case TypeEnum.ValueTwo:
_filter = GetTestObject<FilterValueTwo>();
break;
case TypeEnum.ValueThree:
_filter = GetTestObject<FilterValueThree>();
break;
default:
_filter = null;
break;
}
}
private T GetTestObject<T>()
where T : class
{
// Code simplified
object returnValue = new object();
return (T)returnValue;
}
[TestMethod]
public void Generic_FilterValue_TestMethod()
{
// Error: The type _filter could not be found. (However it exists)
ManipulateData(BuildFilter<_filter>());
}
private void ManipulateData<T>(T filter)
{
// Do some stuff with filter
}
private T BuildFilter<T>()
where T : class
{
// I want filter to be dynamically assigned to whatever _filter was
// assigned to in the constructor (FilterValueOne/Two/Three), instead
// of "FilterValueOne"
var filter = typeof(T);
// Initialize filter data members here...
return filter;
}
}
我最终想在测试方法中使用“ _filter”作为泛型类型参数,但是我无法使其正常工作。我收到一条错误消息,指出“找不到_filter”。
我尝试了多种使用typeof(_filter)等的方法,但没有成功。
我不完全了解泛型及其潜力,我不知道这是否有可能,或者我只是缺少某些东西。
答案 0 :(得分:2)
T
中的BuildFilter<T>
是类型参数。您正在传递类型的实例,在这种情况下,您传递的是object
(又名System.Object
)实例而不是类型。
您根本无法做到这一点,因此会导致编译器错误(_filter
不是 类型;它是一个实例,这就是为什么编译器找不到该“类型”的原因)。 / p>
您要做的是实例化特定的BuildFilter<FilterValueOne>
等,并创建测试这些功能的测试。
例如
[TestMethod]
public void Generic_FilterValueOne_TestMethod()
{
ManipulateData(new BuildFilter<FilterValueOne>());
}
您似乎正在使用MS Test; AFAIK MS Test不支持通用测试,因此您必须为感兴趣的每种类型创建一个测试。
答案 1 :(得分:0)
使用通用测试类更容易,但是如果您希望通过构造器传递过滤器类型,或者将其用作方法参数,则可以使用Activator
类。
public class TestClassGeneric<T> where T : new()
{
public void Generic_FilterValue_TestMethod()
{
var filter = new T();
// ManipulateData(filter);
}
}
public class TestClassConstructorArg
{
private readonly Type type;
public TestClassConstructorArg(Type type)
{
this.type = type;
}
public void Generic_FilterValue_TestMethod()
{
var filter = Activator.CreateInstance(type);
// var filter = Activator.CreateInstance(type, BindingFlags.CreateInstance, arguments...);
// ManipulateData(filter);
}
}