2016-04-15 10 views
1

Ich verwende Apache POI-Methoden zum Schreiben in Excel-Tabellen in Java. Ich muss Unit-Testing für die Methoden durchführen, die ich geschrieben habe. Ich habe viele Methoden von Apache POI verwendet. Soll ich alle Methoden der verschiedenen Objektklassen von Apache POI stubben?Unit-Test von Jar-Methoden in Java

Beispiel: Ich habe Wrapper-Methoden zum Schreiben in eine Zelle erstellt, die Apache POI-Methoden verwenden.

protected void writeCell(int rowNum, int colNum, String value, Sheet sheet) 
{ 
    if(value == null) 
    { 
     return; 
    } 
    Row row = sheet.getRow(rowNum); 
    Cell cell = row.createCell(colNum); 
    cell.setCellValue(); 
    } 

} 

Soll ich spotten sogar die Methoden wie getRow von the Sheet.class und createCell der Zeilenklasse?

+1

Sie müssen keine Unit-Tests für Apache POI-Methoden durchführen, Sie müssen sie nur spotten. Mache auch nur die Methoden, die du benutzt hast, nicht alle –

+0

@KP Ich schreibe keine Testfälle für Apache POI. Ich schreibe für meine eigenen Methoden. – Ashley

Antwort

3

Test auf Ergebnisse, nicht Implementierung.

I.e. Wenn ich eine Zelle schreibe, kann ich diesen Wert jetzt von dieser Zelle zurücklesen?

Auch Sie zeigten uns eine protected Methode, sollten Sie nur die öffentliche Schnittstelle Ihrer Klassen testen müssen. Wenn Sie über die öffentliche Schnittstelle keine Ergebnisse sehen, tut Ihre Klasse wahrscheinlich zu viel (Prinzip der einfachen Verantwortlichkeit).

Die anderen Überlegungen sind jedoch die der Geschwindigkeit und Zerbrechlichkeit, da Apache POI in tatsächliche Dateien liest und schreibt, wird es etwas schwieriger sein, diese Tests zu schreiben, und sie werden langsamer sein. OK für ein paar Tests, aber wenn die ganze Suite Dateien liest und schreibt, dann wird es langsam, und die gesamte Testsuite sollte idealerweise in wenigen Sekunden laufen.

So würde ich eine Schnittstelle erstellen, die eine Excel-Tabelle kapselt und was wollen Sie damit zu tun, könnte dies sein:

public interface StringGrid { 
    String readCell(int rowNum, int colNum); 
    void writeCell(int rowNum, int colNum, String value); 
} 

Nun könnte ich ohne automatisierte Tests eine schnelle Implementierung tun, oder einfach nur ein paar einfache Tests rund um Apache POI, aber dann würde der Rest meiner Suite gegen eine Fake Implementierung der StringGrid testen und ich kann auf die Erstellung von vielen schnelle Tests um mein Code.

diese könnten also wie folgt aussehen:

Die eigentliche Implementierung, nur in seinen Tests und dem Live-Programm verwendet.

public final class ApacheSheetStringGrid implements StringGrid { 

    private final Sheet theApacheSheet; 

    public ApacheSheetStringGrid(Sheet theApacheSheet) { 
     this.theApacheSheet = theApacheSheet; 
    } 

    public String readCell(int rowNum, int colNum){ 
     ... 
    } 

    public void writeCell(int rowNum, int colNum, String value) { 
     Row row = theApacheSheet.getRow(rowNum); 
     Cell cell = row.createCell(colNum); 
     cell.setCellValue(); 
    } 
} 

Die Fälschung (ein funktionierendes, schnelles, speicher nur Implementierung von StringGrid), für alle anderen Tests:

public final class FakeStringGrid implements StringGrid { 

    private final Map<String, String> contents = new HashMap<String, String>(); 

    private static String getKey(int rowNum, int colNum) { 
     return rowNum + ", " + colNum; 
    } 

    public String readCell(int rowNum, int colNum){ 
     return contents.get(getKey(rowNum, colNum)); 
    } 

    public void writeCell(int rowNum, int colNum, String value) { 
     contents.put(getKey(rowNum, colNum), value); 
    } 
} 

Diese zusätzliche Vorteile hat, können Sie später die Live-Umsetzung tauschen für ein anderer, vielleicht mit einem der anderen POI Ansätze oder sogar Google Sheets Implementierung und Sie müssen nur ein paar Tests und eine neue Implementierung hinzufügen und müssen keinen Code ändern (Open Closed Principle).

+0

Dies ist eine wirklich effiziente Lösung. Vielen Dank. Soll ich alle Methoden wie writeCell (int rowNum, int colNum, String-Wert) öffentlich machen, um sie zu testen? Denn dann kann ich geschützte Methoden nicht testen. – Ashley

+0

Nun, wenn Sie dem folgen, werden Methoden wie diese in einer anderen Klasse "öffentlich".Ich schreibe nur "öffentliche" Methoden und schreibe sie nur, um fehlerhafte Tests zu lösen, in meinem Code 'private' und' geschützte' Methoden * nur * durch [Refactoring] (http: //blog.cleancoder. com/Onkel-Bob/2014/12/17/TheCyclesOfTDD.html). – weston

+0

Was meinst du mit "fehlgeschlagene Tests zu lösen"? Wollen Sie damit sagen, dass Sie zuerst alle Methoden als public schreiben und später, wenn Sie später die größere Methode in kleinere Methoden auflösen, als Sie sie als privat/geschützt machen? – Ashley