2009-04-29 13 views
11

In NUnit 2.5 si può fare questo:test parametrico con metodi generici

[TestCase(1,5,7)] 
public void TestRowTest(int i, int j, int k) 
{ 
    Assert.AreEqual(13, i+j+k); 
} 

Si può fare il test parametrico.

Ma mi chiedo se si può fare questo o no, test parametrico con metodo di test generico? I.e .:

[TestCase <int>("Message")] 
public void TestRowTestGeneric<T>(string msg) 
{ 
    Assert.AreEqual(5, ConvertStrToGenericParameter<T>(msg)); 
} 

O qualcosa di simile.

risposta

22

Ecco la citazione dalla nota rilascio di NUnit 2,5 link text

metodi di prova con parametri possono essere generico. NUnit dedurrà l'implementazione corretta da utilizzare in base ai tipi dei parametri forniti. I metodi di test generici sono supportati in clases generici e non generici.

In base a questo, è possibile avere un metodo di test generico in classe non generica. Come?

Non capisco perfettamente il commento di Jeff. In .net generics è sia in fase di compilazione che in fase di esecuzione. Possiamo usare la riflessione per scoprire l'attributo del caso di test associato a un metodo, scoprire il parametro generico e utilizzare nuovamente il reflection per chiamare il metodo generico. Funzionerà, no?

Aggiornamento: OK, ora so come e spero che non sia troppo tardi. È necessario il tipo generico per essere nell'elenco dei parametri. Per esempio:

[TestCase((int)5, "5")] 
[TestCase((double)2.3, "2.3")] 
public void TestRowTestGeneric<T>(T value, string msg) 
{ 
    Assert.AreEqual(value, ConvertStrToGenericParameter<T>(msg)); 
} 
1

Creare un metodo privato e chiamare che:

[Test] 
    public void TypeATest() 
    { 
     MyTest<TypeA>(); 
    } 

    [Test] 
    public void TypeBTest() 
    { 
     MyTest<TypeB>(); 
    } 

    private void MyTest<T>() 
    { 
     // do test. 
    } 
+0

ho avuto usare questo metodo per il mio test che assomiglia a questo: [TestCase (new float [] {1, 2, 3, 4, 5}, new float [] {1, 2, 3, 4, 5}, true)] public void AbleToCompareEqualArrays (T [ ] ar1, T [] ar2, bool expectedValue) –

3

È possibile rendere personalizzato 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); 
    } 

Ecco attuazione 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); 
    } 
} 
+1

Grazie per questo, ho lottato per giorni su come farlo bene e la tua risposta mi ha aiutato finalmente a farlo bene! – AzP