2016-04-19 9 views
0

Ich bin ziemlich neu in der Verwendung von Hamcrest für Behauptungen, und ich habe bereits einen ziemlich bösen Fall zu testen.Werte in verschiedenen benutzerdefinierten Objekten mithilfe von hancrest aktivieren

Wir haben 2 Arraylisten von verschiedenen, benutzerdefinierten Objekten: FilterItem und MyEnum. Beide enthalten eine Eigenschaft - sagen wir "Wert" -, die für die Unittests gleich sein sollte. Da die Objekte unterschiedlich sind, kann ich nicht einfach assertThat (filterItems, hasItems(expectedEnums)), also möchte ich die Werte, die sie enthalten, behaupten, was es viel schwieriger macht.

In jedem Unittest, wo ich diesen geltend zu machen möchte, habe ich die Assertion-Logik auf ein neues Verfahren extrahiert, wie unten dargestellt:

private void assertIfFilterItemValuesAreEqualToExpectedEnumValues(ArrayList<FilterItem> filterItems, ArrayList<MyEnum> expectedEnums) 
{ 
    ArrayList<String> filterItemValues = getFilterItemValues(filterItems); 

    assertEquals(expectedEnums.size(), filterItemValues.size()); 
    // This assert prevents unittests to pass unfairly, in case the array is empty 
    assertFalse("No expectedEnums to assert!", expectedEnums.isEmpty()); 

    for (MyEnum myEnum : expectedEnums) 
    { 
     String myEnumValue = myEnum.getValue(); 
     assertThat(filterItemValues, hasItem(myEnumValue)); 
    } 
} 

private ArrayList<String> getFilterItemValues(ArrayList<FilterItem> filterItems) 
{ 
    ArrayList<String> filterItemValues = new ArrayList<>(); 
    for (FilterWaardeItem filterItem : filterItems) 
    { 
     filterItemValues.add(filterItem.value); 
    } 
    return filterItemValues; 
} 

Die Unittests jetzt alles passieren , so dass ich denke, das Implementierung ist richtig, aber ich habe das Gefühl, die Implementierung könnte einfacher sein. Mein Gefühl ist, dass zumindest die For-Schleife für das Enum weggelassen werden könnte. Wenn die Lösung die 2 vor der for-Schleife auch noch unnötig machen könnte, wäre das großartig! Wahrscheinlich hasProperty() und könnte ein Teil der Lösung sein?

Irgendwelche Ratschläge?

ps. Der aktuelle Test bestätigt nicht, ob die Reihenfolge der Listen identisch ist, aber das ist der nächste Komponententest, den ich erstellen möchte. Wenn jemand auch dafür eine schöne Lösung geben könnte (ohne alle For-Loops zu benutzen), würde ich das sehr schätzen!

Antwort

0

Sie können die tatsächliche und erwartete Liste vorher Karte und dann contains verwenden:

private void assertIfFilterItemValuesAreEqualToExpectedEnumValues(ArrayList<FilterItem> filterItems, ArrayList<MyEnum> expectedEnums) { 
    List<String> actual = filterItems.stream() 
      .map(item -> item.value) 
      .collect(toList()); 
    String[] expected = expectedEnums.stream() 
      .map(myEnum -> myEnum.getValue()) 
      .toArray(String[]::new); 

    assertThat(actual, contains(expected)); 
} 

Dies behaupten auch, dass die Reihenfolge ist das gleiche. Ich habe die neue Stream API für das Mapping verwendet.

0

Sie können die Methode hanccrest contains verwenden, die eine Liste von Matchern akzeptiert. Sie erstellen eine Liste von Matchern aus dem expectedEnums, wobei jedes Element in der Liste ein hasProperty Matcher mit dem Enum in der Liste ist.

final List<Matcher<? super Object>> enumListMatcher = expectedEnums.stream() 
      .map(myEnum -> hasProperty("value", is(myEnum.getValue()))).collect(Collectors.toList()); 
    assertThat(filterItems, contains(enumListMatcher)); 

HINWEIS: es funktioniert, solange Sie einen Getter für value in FilterItem haben.