Devi guardare il pattern "Arrange Act Assert"
.
Per ogni test tu:
Disponi il codice sotto test e qualsiasi variabile dipendente.
Agisci chiamando il metodo sul codice sotto test.
Assert ciò di cui hai bisogno per garantire il test passa (questo dovrebbe essere una cosa per test).
In questo caso utilizzerai:
[TestMethod]
public void MyMethod_CalledWithValidName_HasHelloWorldName()
{
//Arrange
bool isValid = true;
MyObj objectParameter = new MyObj();
ClassUnderTest objectUnderTest = new ClassUnderTest();
//Act
objectUnderTest.MyMethod(objectParameter, isValid);
//Assert
string expectedName = "Hello World";
string actualName = this.myObj.Name;
Assert.AreEqual(expectedName, actualName);
}
Questo ti consente di vedere esattamente cosa stai testando e copiando questo test e cambiando le variabili, scrivi rapidamente test aggiuntivi per altre condizioni.
Nota il modello di denominazione MethodUnderTest_Condition_ExpectedResult
per il test.
Per rispondere effettivamente alla tua domanda:
If I execute the method under TestInitialize, I would need seperate classes per variation of parameter inputs.
Perché? TestInitialize consiste nell'impostare l'ambiente necessario per il test ogni in quella classe ed eseguire prima di ogni test. Nella mia esperienza questi tendono ad essere relativamente piccoli poiché i diversi metodi che si stanno testando hanno dipendenze diverse e dovrebbero essere abbastanza isolati da non dover impostare troppo lo stesso per ogni test. Se è necessario variare gli input dei parametri per ciascun test, allora non appartiene a TestInitialize, appartiene alla parte Arrange del test.
In questa classe hai un test contro un metodo su una classe non specificata (MyMethod) e un test contro myObj. Questi test dovrebbero essere in classi diverse.
Stai confondendo TestInitalize (setup prima di ogni test) come ClassInitialize (setup prima di tutti i test in quella classe).
ClassInitialize può essere abusato e può rendere importante l'ordine dei test. Un test non dovrebbe dipendere da un altro test. Puoi terminare con passaggi / errori in base all'ordine di esecuzione del test, che in alcuni casi non può essere specificato e causare interruzioni quando i test vengono aggiornati o rimossi o eseguiti in isolamento.
Il modo per assicurarsi che myObj.CurrentDateTime non sia nullo quando si prova la classe non specificata è di impostarlo, non si asserirà nulla su quel myObj in quei test. Puoi affermare contro di loro nella classe di test per myObj. Una classe di test per oggetto con un assert per test.
Sembra anche che MyMethod
sia statico. Questo interrompe l'isolamento del test, nel senso che quando il codice in prova viene eseguito funziona con un altro codice di produzione. Questo trasforma questo test in un test di integrazione (poiché il codice sotto test e la classe statica vengono entrambi eseguiti durante il test); questo è negativo perché un errore nella classe statica può causare errori nel codice sotto test in metodi perfettamente funzionanti.
Ho coperto molti aspetti diversi dei test in questa risposta sulla base di molti principi diversi. Prendi il fantastico The Art Of Unit Testing e leggerlo copertinalmente. È una lettura fantastica e di facile lettura ed è uno dei libri che vorrei prendere (insieme al codice completo) se l'ufficio prendesse fuoco.