Там какой-либо путь состоит в том, чтобы передать универсальные типы с помощью TestCase для теста в NUnit?
Это - то, что я хотел бы сделать, но синтаксис не правилен...
[Test]
[TestCase<IMyInterface, MyConcreteClass>]
public void MyMethod_GenericCall_MakesGenericCall<TInterface, TConcreteClass>()
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<TInterface>();
// Assert
Assert.IsInstanceOf<TConcreteClass>(response);
}
Или в противном случае что лучший способ состоит в том, чтобы достигнуть той же функциональности (очевидно, у меня будет несколько TestCases в реальном коде)?
Обновление с другим примером...
Вот другой пример с единственным универсальным переданным типом...
[Test]
[TestCase<MyClass>("Some response")]
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
Атрибуты в C # не могут быть универсальными, поэтому вы не сможете делать то, что вам нужно. Возможно, проще всего было бы поместить атрибуты TestCase
во вспомогательный метод, который использует отражение для вызова реального метода. Что-то вроде этого может сработать (примечание, непроверено):
[TestCase(typeof(MyClass), "SomeResponse")]
public void TestWrapper(Type t, string s)
{
typeof(MyClassUnderTest).GetMethod("MyMethod_GenericCall_MakesGenericCall").MakeGenericMethod(t).Invoke(null, new [] { s });
}
Сначала начните с теста - даже во время тестирования. Что ты хочешь делать? Вероятно, что-то вроде этого:
[Test]
public void Test_GenericCalls()
{
MyMethod_GenericCall_MakesGenericCall<int>("an int response");
MyMethod_GenericCall_MakesGenericCall<string>("a string response");
:
}
Тогда вы можете просто сделать свой тест простым старым функциональным тестом. Нет маркера [Test].
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
На прошлой неделе я делал нечто подобное. Вот что у меня получилось:
internal interface ITestRunner
{
void RunTest(object _param, object _expectedValue);
}
internal class TestRunner<T> : ITestRunner
{
public void RunTest(object _param, T _expectedValue)
{
T result = MakeGenericCall<T>();
Assert.AreEqual(_expectedValue, result);
}
public void RunTest(object _param, object _expectedValue)
{
RunTest(_param, (T)_expectedValue);
}
}
И затем сам тест:
[Test]
[TestCase(typeof(int), "my param", 20)]
[TestCase(typeof(double), "my param", 123.456789)]
public void TestParse(Type _type, object _param, object _expectedValue)
{
Type runnerType = typeof(TestRunner<>);
var runner = Activator.CreateInstance(runnerType.MakeGenericType(_type));
((ITestRunner)runner).RunTest(_param, _expectedValue);
}