2010-04-15 1 views
5

Sono un neofita del mocking/testing e voglio sapere a che livello si dovrebbe andare quando si esegue il test. Per esempio nel mio codice ho il seguente oggetto:Come creare test per oggetti poco.

public class RuleViolation 
{ 
    public string ErrorMessage { get; private set; } 
    public string PropertyName { get; private set; } 

    public RuleViolation(string errorMessage) 
    { 
     ErrorMessage = errorMessage; 
    } 

    public RuleViolation(string errorMessage, string propertyName) 
    { 
     ErrorMessage = errorMessage; 
     PropertyName = propertyName; 
    } 
} 

Questo è un oggetto relativamente semplice. Quindi la mia domanda è:

Ha bisogno di un test unitario?

Se fa cosa testare e come?

Grazie

+0

Vedere il mio aggiornamento a come si dovrebbe verificare se il setter è privato. – kemiller2002

risposta

4

non direi probabilmente. L'unica cosa che si sarebbe probabilmente desidera verificare se è estremamente importante sono i modificatori di accesso:

public string ErrorMessage { get; private set; } 
public string PropertyName { get; private set; } 

Se è davvero molto importante che il codice al di fuori della classe non può modificare loro che potrebbe essere l'unica cosa che vorrei provare e verificare.

Ecco come è possibile ottenere le funzioni di accesso in una proprietà:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var property = typeof(Test).GetProperty("Accessor"); 

      var methods = property.GetAccessors(); 
     } 
    } 



    public class Test 
    { 
     public string Accessor 
     { 

      get; 
      private set; 
     }  

    } 

Con il property.GetAccessors();

Si può vedere se il setter è lì. Se lo è, allora il setter è pubblico. (Esistono anche le proprietà IsPrivate e IsPublic che è possibile utilizzare per verificare anche gli altri Accessors).

+0

+1 questo è il tipo di cosa che è difficile notare dal momento che il codice si evolve nel tempo ed è così semplice da testare, c'è poco motivo per non provare – Cocowalla

+0

come si testerebbe qualcosa del genere? Come non puoi provare a impostare una proprietà in quanto mostra un errore del compilatore? O mi sto perdendo qualcosa di semplice? – lancscoder

+0

+1 Test molto bello che hai qui! Magra e veloce, proprio come piace a noi! Grazie! –

7

non contiene alcuna logica => niente da testare

+0

+1 Grazie per questa semplice regola di test. –

0

Anche se semplice, c'è logica nei vostri costruttori. Ho iniziato ad esaminare che:

RuleViolation ruleViolation = new RuleViolation("This is the error message"); 
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage); 
Assert.IsEmpty(ruleViolation.PropertyName); 

RuleViolation ruleViolation = new RuleViolation("This is the error message", "ThisIsMyProperty"); 
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage); 
Assert.AreEqual("ThisIsMyProperty", ruleViolation.PropertyName); 
1

È potrebbe unit test questo oggetto, ma è così semplice da non richiedere esso. Il test sarebbe qualcosa di simile (NUnit esempio)

[Test] 
public void TestRuleViolationConstructorWithErrorMessageParameterSetsErrorMessageProperty() { 
    // Arrange 
    var errorMessage = "An error message"; 

    // Act 
    var ruleViolation = new RuleViolation(errorMessage); 

    // Assert 
    Assert.AreEqual(errorMessage, ruleViolation.ErrorMessage); 
} 

C'è poco valore alla scrittura dei test come questi, tuttavia, come si sta testando che le proprietà del framework .NET funzionano correttamente. Generalmente puoi fidarti di Microsoft per avere ragione :-)

Per quanto riguarda il mocking, questo è utile quando la tua classe in prova ha una dipendenza, magari su un'altra classe nella tua applicazione, o su un tipo da un framework. I framework di simulazione consentono di chiamare metodi e proprietà sulla dipendenza senza il problema di creare concretamente la dipendenza nel codice e consentono invece di immettere valori definiti per le proprietà, valori di ritorno per i metodi, ecc. è un framework eccellente e un Test per una classe base con dipendenza sarebbe simile a questa:

[Test] 
public void TestCalculateReturnsBasicRateTaxForMiddleIncome() { 
    // Arrange 
    // TaxPolicy is a dependency that we need to manipulate. 
    var policy = new Mock<TaxPolicy>(); 
    bar.Setup(x => x.BasicRate.Returns(0.22d)); 

    var taxCalculator = new TaxCalculator(); 

    // Act 
    // Calculate takes a TaxPolicy and an annual income. 
    var result = taxCalculator.Calculate(policy.Object, 25000); 

    // Assert 
    // Basic Rate tax is 22%, which is 5500 of 25000. 
    Assert.AreEqual(5500, result); 
} 

TaxPolicy sarebbe unità testato nel proprio dispositivo per verificare che si comporta correttamente. Qui, vogliamo verificare che il funzioni correttamente e quindi prendiamo in giro l'oggetto TaxPolicy per semplificare i nostri test; così facendo, possiamo specificare il comportamento dei soli bit di TaxPolicy a cui siamo interessati. Senza di esso, avremmo bisogno di creare mock/stub/falsi laminati a mano o creare istanze reali di TaxPolicy da passare in giro.

Tuttavia, a Moq c'è molto di più di questo; controlla il quick-start tutorial per vedere di più di quello che può fare.

1

Se fosse il mio codice e il mio oggetto, farei dei test per questo, non importa quanto semplice o complicata sia la classe, punto. Anche se sembra improbabile che la classe si rompa, i test sono dove, IMO, documenti le tue ipotesi, le decisioni di progettazione e il corretto utilizzo.

In tal modo, non solo si convalida che ciò che si lavora funziona come previsto, ma si ha l'opportunità di pensare attraverso scenari tipici (cosa succede se i parametri del ctor sono nulli o vuoti o hanno uno spazio bianco alla fine? il PropertyName è facoltativo in una classe immutabile?).

E se i requisiti IF (quando?) Cambiano, si ha un solido punto di partenza per affrontarlo. E SE questa classe banale in qualche modo non interagisce bene con tutte le altre classi, si può avere un test per catturarlo prima che i tuoi clienti facciano.

È il modo giusto per progettare il codice.

HTH,
Berryl