2017-05-16 3 views
3

Ich studiere für meine ersten Vorstellungsgespräche als Junior Java Developer und im Moment versuche ich, JUnit Testfälle zu lernen. Dies ist ein Beispiel, dem ich begegnet bin, und ich muss sagen, es ist wirklich schwierig für mich (es ist abstrakter Code, also habe ich keine Ahnung, wie ich es testen soll).JUnit Testfälle für benutzerdefinierte Methode

public class JuiceMaker { 

    public Juice makeJuice(final List<Fruit> fruits) throws RottenFruitException { 
    for (final Fruit fruit : fruits) { 
     if (FruitInspector.isFruitRotten(fruit)) { 
     throw new RottenFruitException(fruit.getName() + “ is rotten. Cannot make juice.”); 
     } 
    } 

    return Juicer.juice(fruits); 
    } 
} 

Das einzige Beispiel, das ich mich selbst zu schaffen verwaltet ist dieser:

JuiceMaker jm = new JuiceMaker(); 

@Test 
public void isThrowingException() { 
//when 
    try { 
     jm.throwsRuntime(); 
     Assert.fail("Expected exception to be thrown"); 
    } catch (RottenFruitException e) { 
//then 
     assertThat(e) 
      .isInstanceOf(RottenFruitException.class) 
      .hasMessage((fruit.getName() + " is rotten. Cannot make juice."); 
    } 
} 

Irgendwelche Tipps, welche Art von Tests, die ich auf diesem Stück Code ausführen kann? Vielen dank für Deine Hilfe!

+1

Ich denke, Sie sollten diese Frage auf einer anderen Stackoverlfow-Site stellen, wie eine Quellenbewertung. –

+0

Es wäre einfacher, Ihre Frage zu beantworten, wenn Sie den Code für Fruit, FruitInspector, Juicer und abhängig von der Implementation Juice angeben. Außerdem verweisen Sie in Ihrem Testbeispiel auf die Methode "throwsRuntime", die in der JuiceMaker-Klasse nicht definiert ist. Geben Sie daher auch die vollständige Definition dieser Klasse an. Das letzte: In Ihrem Beispiel greifen Sie auf ein Fruchtobjekt zu, aber es ist nicht definiert. – gawi

+0

Ich habe keine Implementierung für diese Methoden. Das ist alles, woran ich arbeiten kann: "In Test-getriebenen Entwicklungstests sollte die Implementierung dokumentiert sowie getestet werden. In diesem Sinne schreiben Sie Tests für diesen Legacy-Code. Dann refactor, um implizite Abhängigkeiten zu entfernen." –

Antwort

3

Willkommen bei JUnit, und viel Glück bei Ihren Interviews!

Erste Frage zu stellen ist, was ist der Vertrag von dieser Klasse angeboten? Es braucht eine Liste von Früchten, testet, ob irgendwelche der Früchte faulig sind, wenn es so eine Ausnahme gibt, sonst saft es sie. Sie können davon ausgehen, dass die "Saft" -Methode an anderer Stelle getestet wird.

Für mich, das legt nahe, diese Tests:

  • Liste mit Einzel gute Früchte
  • Liste mit Einzel faule Frucht
  • Liste mit mehreren guten und eine faule Frucht
  • Leere Liste

Sie könnten auch nach Null und ungültigen Werten suchen, aber das könnte jetzt gerade übertrieben werden.

Sobald Sie entschieden haben, was Sie testen sollen, können Sie über die Implementierung nachdenken. Es sieht so aus, als ob Ihre Implementierung einige Fehler aufweist, aber Sie befinden sich in einer guten Richtung. Möglicherweise finden Sie den JUnit-Parameter "expected", der für das Testen auf Ausnahmen nützlich ist.

2

Sie scheinen die JuiceMaker Instanz in Ihrem Test anzuweisen, die Ausnahme zu werfen, um zu überprüfen, ob Sie sie abfangen können.

Sie müssen selbst beantworten, ob das alleine die Schleife durchläuft, die durch die Liste Fruit und die if() Anweisung iteriert.

Sie können die JuiceMaker.makeJuice() besser beeinflussen, indem Sie verschiedene Listen (null, leer, ohne faule Früchte, mit faulen Früchten) übergeben.

Auf diese Weise erzwingen Sie keine Ausnahmen, sondern verursachen sie - was mehr Pfade durch den zu testenden Code ausübt.

Wenn Sie die oben genannten Szenarien ausführen, sollten Sie eine sehr gute Testabdeckung Ihrer Methode haben.

Hoffe, das hilft!

2

Die zwei Testfälle, die Sie in Ihrem Beispiel-Antwort aufstellen, gehen in die richtige Richtung, aber nur halbwegs. Da beide Tests überhaupt nicht testen Sie Ihre "Klasse unter Test".

Angemessene Tests würden mehr wie folgt aussehen:

public class JuiceMakerTest { 
    private JuiceMaker underTest; 

    @Before 
    public void setup() { underTest = new JuiceMaker; } 

    @Test(expected=RottenFruitException.class) 
    public void testThrowsOnRottenFruit() { 
    underTest.makeJuice(Collections.singletonList("rotten apple")); 
    } 

    @Test(expected=???) 
    public void testWithNullList() { 
    underTest.makeJuice(null); 
    } 

    @Test(expected=???) 
    public void testWithEmptyList() { 
    underTest.makeJuice(Collections.emptyList()); 
    } 

    @Test 
    public void testXyz() { 
    Juice expectedResult = ... 
    assertThat(underTest.makeJuice(Collections.singletonList("apple")), is(expectedResult); 
    } 

und so weiter. Mit anderen Worten: Sie folgen der netten Antwort von Hugh; und ermitteln Sie die möglichen Methoden zum Aufrufen Ihrer Methode. Die ??? ist nur ein Platzhalter - darauf hinweist, dass Sie sollten sich überlegen, was hier passieren soll. Vielleicht erwarten Sie eine bestimmte Ausnahme; vielleicht gibt die Methode einen speziellen leeren Saft zurück ... alles bis zum Vertrag der zu testenden Methode.

Daraus leiten Sie Fehlerbedingungen und erwartete Ergebnisse ab. Und dann schreibst du mindestens einen Test für die verschiedenen Aspekte, die du gesammelt hast.

Verwandte Themen