2016-08-30 1 views
0

Beim Versuch, Testfälle für eine Klasse zu schreiben, deren Funktionalität mehr mit Kesselblechcode als Geschäftslogik arbeitet. Ich begann mich zu fragen, ob Unit Testing wirklich für diesen Kurs wert ist. Aber dann, wenn TDD verwendet wird, ist es ratsam, einen Test für jede Logik, die wir hinzufügen, zu schreiben.Einheit, die das Offensichtliche prüft

Als Beispiel die folgende Klasse verwendet nur DI, um Abhängigkeiten zu injizieren und Konfigurationsparameter zu erhalten, um den Ablauf der Anwendung einzurichten. Anders als bei Komponententests, wenn Abhängigkeiten korrekt injiziert werden, oder wenn beim Beenden der Befehl destroy aufgerufen wird (was das Unit-Testen des Java-CDI-Frameworks als mein eigener Code wäre), was kann ich sonst Unit-Test machen?

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.inject.Inject; 

@Singleton 
@Startup 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public class PipsAlprConnectionRunner { 
    @Inject 
    private PipsAlprConfiguration config; 

    @Inject 
    private PipsAlprConnector connector; 

    @Inject 
    private Scheduler scheduler; 

    @Inject 
    @PipsAlprAdapterService 
    private ServiceStatus status; 

    private Timer connectorTimer = null; 

    @PostConstruct 
    public void initialized() { 
     status.started(); 
     connectorTimer = scheduler.schedule(connector, 0, 
       1000 * config.getPollPeriodSeconds()); 
     status.operational(); 
    } 

    @PreDestroy 
    public void destroy() { 
     connectorTimer.cancel(); 
     connector.shutdown(); 
     status.stopped(); 
    } 
} 

ich nicht in der Lage war von irgendwelchen Testszenarien zu denken TDD zu nutzen, auf der oben genannten Klasse, kam so nur mit dem Code, und jetzt frage ich mich, was genau kann ich hier Unit-Test.

Antwort

1

Nun, ein Fall kann gemacht werden, dass die Klasse etwas tut. Es ändert einen Status, es startet einen Timer. Sie können Mocks dieser Objekte über Mockito in die Klasse injizieren und dann sicherstellen, dass initialized() und destroy() beide tun, was Sie von diesen Mocks erwarten.

@RunWith(MockitoJUnitRunner.class) 
public class PipsAlprConnectionRunner { 

    @Mock 
    private PipsAlprConfiguration config; 

    @Mock 
    private PipsAlprConnector connector; 

    @Mock 
    private Scheduler scheduler; 

    @Mock 
    private ServiceStatus status;  

    @InjectMocks 
    private PipsAlprConnectionRunner pipsAlprConnectionRunner ; 

    @Test 
    public void initialized_should_set_status_started() { 
     pipsAlprConnectionRunner.initialized(); 
     Mockito.verify(status).started(); 
    } 

    // etc. 
} 

Es ist so ziemlich eine Frage des persönlichen Geschmacks, wenn Sie per „Point of Failure“ eine Methode erstellen möchten oder eine Methode pro Verfahren/Test.

Persönlich würde ich sagen, dass das Ziel 100% Abdeckung ist, also selbst ziemlich einfache Klassen, die hauptsächlich Delegieren sollten abgedeckt werden. Was passiert, wenn jemand etwas ändert? Der Test stellt sicher, dass solche Änderungen die vorhandene Funktionalität nicht beeinträchtigen.

+0

Also ich glaube, dass die PipsAlprConnectionRunner-Klasse, die Sie definiert haben, tatsächlich eine Testklasse ist anders als die tatsächliche PipsAlprConnectionRunner? Und alle Objekte werden mit Mock-Implementierung über DI eingefügt? Wie wäre es mit dem Komponententest, bei dem Sie überprüfen, ob die Abhängigkeit tatsächlich injiziert wird? Aber ich glaube, dass solch ein Test nutzlos ist, da CDI-Injektion nicht während eines Unit-Testlaufs stattfindet. – Saad

+0

Nein, der 'PipsAlprConnectionRunner' ist eigentlich dein' PipsAlprConnectionRunner'. Mockito erstellt einen und injiziert die verspotteten Abhängigkeiten hinein, das ist die Magie von @InjectMocks. Persönlich würde ich die DI nicht selbst testen, da dies das Framework effektiv testen würde (ok, wir könnten ein Argument für die Idee machen) dass wir testen, ob die richtigen Annotationen da sind). Ich würde einfach zu einem späteren Zeitpunkt noch einige Integrationstests durchführen, die ohnehin von DI abhängen und dies automatisch testen. –

+0

Ich sehe Danke! Auch, da die Methode started() und destroy() den internen Zustand von PipsAlprConnectionRunner ändern, ist die einzige Möglichkeit, sie zu testen, die Verhaltensverifizierung und die Statusverifizierung. Aber das kann nur durch Mock-Objekte geschehen, was wäre, wenn wir nicht ein spöttisches Framework benutzen würden? Oder wie würden Menschen Unit-Tests an Objekten durchführen, deren Zustand vor dem Aufkommen von Mock-Objekten schwer zu überprüfen war? – Saad

Verwandte Themen