2016-04-01 2 views
2

Извините за это название, которое я стараюсь сделать как можно более ясным. Не стесняйтесь редактировать, чтобы направить его.Тестирование содержимого атрибута коллекции из коллекции объектов

Моя проблема заключается в том, что я хотел бы проверить содержание этой структуры и более специальным образом содержания объектов B и убедиться, что она соответствует определенным значениям A:

public class A { 
    String key; 
    List<B> bs; 
} 

И мои данные имеют эту форму

List<A> as = [ 
    { 
     key : "KEY1", 
     bs: [ 
      {val1:"val1", val2:"val2} 
     ] 
    }, 
    { 
     key : "KEY2", 
     bs: [ 
      {val1:"val3", val2:"val4"}, 
      {val1:"val5", val2:"val6"} 
     ] 
    }, 
]; 

в контексте тестирования единицы с Mockito, я хотел бы быть в состоянии проверить эту структуру, не делая предварительно лечение, чтобы получить список B. Проверяя эту структуру, я хотел бы быть уверен, что есть два B для KEY2 и что первый B имеет val3 и val4, второй val5 и val6.

На данный момент мне нужно создать карту по ключу и проверить каждую запись. Я хотел бы сделать это более простым способом, если таковые существуют.

Вот мой фактический тест.

List<A> as = captor.getAllValues(); 
assertThat(as) 
      .isNotNull() 
      .hasSize(2) 
      .extracting("key") 
      .containsOnlyOnce(
        tuple("KEY1"), 
        tuple("KEY2") 
      ); 

    Map<String, A> estimationParPlateforme = indexBy(as, new Indexer<String, A>() { 
     @Override 
     public String apply(A a) { 
      return a.getKey(); 
     } 
    }); 

assertThat(as.get("KEY1").getBs()) 
      .isNotEmpty() 
      .extracting(
        "val1", 
        "val2" 
      ) 
      .containsExactly(
        tuple(
          "val1", 
          "val2" 
        ) 
      ); 

assertThat(as.get("KEY2").getBs()) 
      .isNotEmpty() 
      .extracting(
        "val1", 
        "val2" 
      ) 
      .containsExactly(
        tuple(
          "val3", 
          "val4" 
        ), 
        tuple(
          "val5", 
          "val6" 
        ) 
      ); 

Я думаю, что это немного дольше для испытания, и я хотел бы найти способ улучшить это. У вас есть решение?

Спасибо за любую помощь

+0

'assertThat (as) .extracting (" bs ")' и т. Д.? –

ответ

1

Вы должны определить, каким образом структура данных должна выглядеть. На данный момент у вас есть вся эта информация, разбросанная в ваших тестовых заявлениях. Это делает его очень уродливым, как вы все уже поняли. То, что мне нравится делать, это иметь некоторую структуру данных, которую я могу заполнить данными, которые я ожидаю. Тогда я могу использовать это, чтобы проверить, действительно ли мои данные или нет. Пример:

static Map<String, B[]> expectedBs = new HashMap<String, B[]>(); 

public static void main(String[] args) { 
    //put the expected values into a map 
    expectedBs.put("KEY1", new B[] { new B("val1", "val2") }); 
    expectedBs.put("KEY2", new B[] { new B("val3", "val4"), new B("val5", "val6") }); 

    //build a valid datastructure 
    List<A> as = new ArrayList<A>(); 
    List<B> bs1 = new ArrayList<B>(); 
    bs1.add(new B("val1", "val2")); 

    List<B> bs2 = new ArrayList<B>(); 
    bs2.add(new B("val3", "val4")); 
    bs2.add(new B("val5", "val6")); 

    as.add(new A("KEY1", bs1)); 
    as.add(new A("KEY2", bs2)); 


    //test validity of as 
    System.out.println(isValid(as)); //prints true 

    //modify the datastructure such that it is not valid anymore 
    bs1.get(0).val1 = "val2"; 

    //test validity once more 
    System.out.println(isValid(as)); //prints false 
} 

static boolean isValid(List<A> as) { 
    for (A a : as) { 
     B[] expected = expectedBs.get(a.key); 
     if (!equals(a.bs, expected)) 
      return false; 
    } 
    return true; 
} 

static boolean equals(List<B> x, B[] y) { 
    if (x == null) 
     return false; 
    if (y == null) 
     return false; 
    if (x.size() != y.length) 
     return false; 
    for (int i = 0; i < x.size(); i++) 
     if (!x.get(i).equals(y[i])) 
      return false; 
    return true; 
} 

А:

public class A { 
    String key; 
    List<B> bs; 

    public A(String key, List<B> bs) { 
     this.key = key; 
     this.bs = bs; 
    } 
} 

Б:

public class B { 
    String val1, val2; 
    public B(String val1, String val2) { 
     this.val1 = val1; 
     this.val2 = val2; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) 
      return false; 
     if (!(obj instanceof B)) 
      return false; 
     B objB = (B) obj; 
     if (!objB.val1.equals(this.val1)) 
      return false; 
     if (!objB.val2.equals(this.val2)) 
      return false; 
     return true; 
    } 
} 

Извините за код неоспоримым так долго. Надеюсь, вы получите эту идею. Является ли это более элегантным или нет, вам решать.

+0

Спасибо, что ответили. Ваше решение действительно интересно. Я помню это. Я действительно искал способ «Mockito» сделать это. Еще раз спасибо – RPresle

+0

@RPresle О, я вижу, его об модульных тестах с Mockito. Вы должны поставить это в свой вопрос где-нибудь. –

+0

Готово. спасибо вам – RPresle

Смежные вопросы