У меня есть интерфейс с обобщениями, который реализован некоторыми классами. Для каждого из этих классов есть прокси-класс, который также реализует интерфейс. Примерно такой код:
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: атрибут TestClass не может быть определен в универсальном классе ISomeInterfaceTests .
Есть ли хороший обходной путь к этому? В настоящее время лучшее решение, которое я могу придумать, это иметь метод в ClassAProxyTests, который вызывает различные методы тестирования в ISomeInterfaceTests . Однако у этого подхода есть несколько проблем:
- Это нужно сделать вручную для каждого теста, реализующего ISomeInterfaceTests .
- Если один из методов приведет к ошибочному утверждению, остальные методы не будут выполнены.
- Вы не можете использовать атрибут ExpectedException и должны обернуть необходимый код в операторах try catch.
но, увы, лучшее решение ускользает от меня.