Test paramétrique avec méthodes génériques
-
03-07-2019 - |
Question
Dans NUnit 2.5, vous pouvez faire ceci:
[TestCase(1,5,7)]
public void TestRowTest(int i, int j, int k)
{
Assert.AreEqual(13, i+j+k);
}
Vous pouvez faire un test paramétrique.
Mais je me demande si vous pouvez faire cela ou non, test paramétrique avec méthode de test générique? I.e.:
[TestCase <int>("Message")]
public void TestRowTestGeneric<T>(string msg)
{
Assert.AreEqual(5, ConvertStrToGenericParameter<T>(msg));
}
Ou quelque chose de similaire.
La solution
Voici la citation de la note de publication de NUnit 2.5 texte du lien
Les méthodes de test paramétrées peuvent être générique. NUnit va déduire le bon mise en œuvre à utiliser en fonction de la types de paramètres fournis. Les méthodes de test génériques sont supportées dans à la fois des classes génériques et non génériques.
Selon cela, il est possible d’avoir une méthode de test générique dans une classe non générique. Comment?
Je ne comprends pas très bien le commentaire de Jeff. Dans .net, les génériques sont à la fois compilation et exécution. Nous pouvons utiliser la réflexion pour déterminer l'attribut de scénario de test associé à une méthode, connaître le paramètre générique et utiliser à nouveau la réflexion pour appeler la méthode générique. Cela fonctionnera, non?
Mise à jour: OK, je sais maintenant comment et j'espère qu'il n'est pas trop tard. Le type générique doit figurer dans la liste des paramètres. Par exemple:
[TestCase((int)5, "5")]
[TestCase((double)2.3, "2.3")]
public void TestRowTestGeneric<T>(T value, string msg)
{
Assert.AreEqual(value, ConvertStrToGenericParameter<T>(msg));
}
Autres conseils
Vous pouvez personnaliser GenericTestCaseAttribute
[Test]
[GenericTestCase(typeof(MyClass) ,"Some response", TestName = "Test1")]
[GenericTestCase(typeof(MyClass1) ,"Some response", TestName = "Test2")]
public void MapWithInitTest<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
Voici l'implémentation de GenericTestCaseAttribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class GenericTestCaseAttribute : TestCaseAttribute, ITestBuilder
{
private readonly Type _type;
public GenericTestCaseAttribute(Type type, params object[] arguments) : base(arguments)
{
_type = type;
}
IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
{
if (method.IsGenericMethodDefinition && _type != null)
{
var gm = method.MakeGenericMethod(_type);
return BuildFrom(gm, suite);
}
return BuildFrom(method, suite);
}
}
Créez une méthode privée et appelez-la:
[Test]
public void TypeATest()
{
MyTest<TypeA>();
}
[Test]
public void TypeBTest()
{
MyTest<TypeB>();
}
private void MyTest<T>()
{
// do test.
}