我有一个由一些类实现的泛型接口。对于这些类中的每一个,都有代理类来实现接口。大致给出这段代码:
public interface ISomeInterface<T>
{
T SomeProperty
{
get;
}
T SomeAction();
}
public interface IClassA : ISomeInterface<string>
{
void Action();
}
public class ClassA : IClassA
{
// Code goes here
}
public class ClassAProxy : IClassA
{
// Code goes here
}
单元测试代码我希望看起来像这样:
public abstract class ISomeInterfaceTests<T>
{
[TestMethod()]
public void SomePropertyTest()
{
ISomeInterface<T> target;
ISomeInterface<T> oracle;
this.CreateInstance(out target, out oracle);
Assert.AreEqual(oracle.SomeProperty, target.SomeProperty);
}
[TestMethod()]
public void SomeActionTest()
{
ISomeInterface<T> target;
ISomeInterface<T> oracle;
this.CreateInstance(out target, out oracle);
T oracleValue = oracle.SomeAction();
T targetValue = target.SomeAction();
Assert.AreEqual(oracleValue, targetValue);
}
// More tests
protected abstract void CreateInstance(out ISomeInterface<T> target, out ISomeInterface<T> oracle);
}
[TestClass()]
public class ClassAProxyTests : ISomeInterfaceTests<string>
{
// ClassAProxy specific tests
protected override void CreateInstance(out ISomeInterface<string> target, out ISomeInterface<string> oracle)
{
// Create target as ClassAProxy here and oracle as ClassA
}
}
但是这给出了错误: UTA002:无法在泛型类ISomeInterfaceTests&lt; T&gt;上定义TestClass属性。
这有什么好的解决方法吗?目前我能想到的最好的解决方案是在ClassAProxyTests中使用一个方法来调用ISomeInterfaceTests&lt; T&gt;中的不同测试方法。但是这种方法有几个问题:
但唉,一个更好的解决办法让我感到安心。
答案 0 :(得分:1)
听起来您需要使用GenericTestFixture 2.5的NUnit功能。此功能允许您将[TestFixture]
属性放在泛型类上,然后指定测试夹具的哪些特化适用。
您的主要测试夹具将如下所示(您也可以删除一些接口):
[TestFixture(typeof(string))]
public class ClassAProxyTests<T> : ISomeInterfaceTests<T> where T: class
{
// Add ISomeInterfaceTests<T> methods here.
// ISomeInterfaceTests may no longer be required as the abstraction is defined in ClassAProxyTests.
// ClassAProxy specific tests
protected override void CreateInstance(out ISomeInterface<T> target, out ISomeInterface<string> oracle)
{
// Create target as ClassAProxy here and oracle as ClassA
}
}
答案 1 :(得分:0)
你拥有父类的唯一原因是创建你的界面实例,是吗?
请改用MOQ。
修改:
嗯......这听起来像是一个集成测试。你的oracle对象是以某种方式从数据库中读取的,还是你嘲笑它们就像你应该的那样?无论如何,我一直使用Moq来获取你的实例和模拟与集成测试。不完全。 ISomeInterfaceTests&lt; T&gt; class用于测试实现ISomeInterface&lt; T&gt;的代理的功能。 interface - 它根据代理对象(oracle)来测试代理。 - Cornelius
但令我感到震惊的是,您的测试一般化方法可能就是问题所在。也许是另一种方法?试试这个:
public static class GenericISomeInterfaceTests
{
public static void SomePropertyTest<T>(ISomeInterface<T> target, ISomeInterface<T> oracle)
{
Assert.AreEqual(oracle.SomeProperty, target.SomeProperty);
}
public static void SomeActionTest<T>(ISomeInterface<T> target, ISomeInterface<T> oracle)
{
T oracleValue = oracle.SomeAction();
T targetValue = target.SomeAction();
Assert.AreEqual(oracleValue, targetValue);
}
// More tests
}
[TestClass()]
public class ClassAProxyTests
{
[TestMethod]
public void SomePropertyStringTest()
{
// set up instances (using MOQ, or whatever) with the string generic type.
// Call them target and oracle
// then call your generic test methods
GenericISomeInterfaceTests.SomePropertyTest<string>(target, oracle);
}
[TestMethod]
public void SomeActionStringTest()
{
// set up instances (using MOQ, or whatever) with the string generic type.
// Call them target and oracle
// then call your generic test methods
GenericISomeInterfaceTests.SomeActionTest<string>(target, oracle);
}
}