2012-06-29 2 views
6

Dire che ho il seguente:Esiste un modo per eseguire un elenco di diversi metodi di azione su un oggetto in Nunit utilizzando TestCase?

[Test] 
    // would like to parameterize the parameters in call AND the call itself 
    public void Test() 
    { 
     var res1 = _sut.Method1(1); 
     var res2 = _sut.Method2("test"); 
     var res3 = _sit.Method3(3); 

     Assert.That(res1, Is.Null); 
     Assert.That(res2, Is.Null); 
     Assert.That(res3, Is.Null); 
    } 

vorrei parametrizzare i test utilizzando l'attributo TestCase/TestCaseSource tra cui la chiamata stessa. A causa della natura ripetitiva dei test, ogni metodo deve essere chiamato con parametri leggermente diversi, ma devo essere in grado di taggare una chiamata diversa per ciascuno dei diversi parametri. Questo è possibile anche in Nunit? Se è così, come potrei farlo?

+0

Ciao. So che questo è facilmente possibile usando MbUnit ... Con NUnit, penso che potresti farlo usando un DB e memorizzando il valore in questo DB, quindi parametrizza il tuo test con un'origine dati – Kek

risposta

5

Utilizzando TestCaseSource, si dovrebbe essere in grado di ciclo su una matrice di valori e richiamare i metodi desiderati, per esempio come questo:

[TestFixture] 
public class TestClass 
{ 
    private Sut _sut; 

    public TestClass() 
    { 
    _sut = new Sut(...); 
    } 

    private IEnumerable<object> TestCases 
    { 
    get 
    { 
     var values = new object[,] { { 1, "test", 3 }, { 2, "hello", 0 }, ... }; 

     for (var i = 0; i < values.GetLength(0); ++i) 
     { 
      yield return _sut.Method1((int)values[i,0]); 
      yield return _sut.Method2((string)values[i,1]); 
      yield return _sut.Method3((int)values[i,2]); 
     } 
    } 
    } 

    [TestCaseSource("TestCases")] 
    public void Test(object val) 
    { 
    Assert.That(val, Is.Null); 
    } 
} 

noti che l'istanza _sut deve essere istanziata nel costruttore TestClass. Non è sufficiente inizializzarlo con un metodo [SetUp] o [TestFixtureSetUp].

In caso di necessità diverse _sut istanze per le diverse chiamate di metodo, è possibile creare una raccolta di Sut casi nel costruttore, e accedere alla relativa voce di Sut all'interno del for ciclo del TestCases getter. In alternativa, è anche possibile eseguire il loop su tutti gli articoli Sut nel getter ...

+0

Suggerimento interessante, comunque sto ottenendo 'impossibile convertire il tipo di espressione' espressione lambda 'per restituire il tipo Tuple , oggetto> ... – jaffa

+0

Ho aggiornato l'esempio, ma cercherò di approfondire il codice. Torneremo il prima possibile. –

+0

L'ho esagerato la prima volta :-) E l'esempio aggiornato? –

0

Afaik, non esiste un meccanismo integrato di questo tipo in NUnit. Tuttavia, se esistono più metodi in un test, penso che sarebbe una buona pratica dividerli in test separati.

Detto questo, purché si chiamino sempre questi metodi sullo stesso oggetto (_sut), è possibile farlo con la riflessione (anche se si decide di sostenere l'overhead sostenuto).

Ad esempio, aggiungere un parametro di stringa nella vostra TestCaseSource, e nel metodo di prova invocare in questo modo:

Type type = _sut.GetType(); 
MethodInfo methodInfo = type.GetMethod(methodName); 
object result = methodInfo.Invoke(_sut, null); 

le cose andranno rapidamente complicarsi quando ogni metodo che si desidera parametrizzare avrà un diverso numero di argomenti però. Anche il debugging e vedere quale test fallire sarà molto più difficile. È meglio se tu potessi dividere questi test.

+0

Sì, io penso che sia bello, è eccessivo . Ho ridotto il no. linee in ogni Test creando metodi di supporto, quindi non è male ripetere i test. Tuttavia, penso che questo genere di cose sarebbe utile per testare macchine di stato ecc ... – jaffa