问题描述:

Sorry for this title that I try to make as clear as possible. Don't hesitate to edit to impove it.

My problem is that I would like to test the content of this structure and more specialy the content of B objects and assure that it correspond to specific A values :

public class A {

String key;

List<B> bs;

}

And my data have this form

List<A> as = [

{

key : "KEY1",

bs: [

{val1:"val1", val2:"val2}

]

},

{

key : "KEY2",

bs: [

{val1:"val3", val2:"val4"},

{val1:"val5", val2:"val6"}

]

},

];

In the context of Unit testing with Mockito, I would like to be able to test this structure without doing a pre treatment to get the List of B. By testing this structure I would like to be sure that there are two B for KEY2 and that first B has val3 and val4, the second val5 and val6.

At the moment, I have to create a map by key and test every entry. I would like to it in a more straightforward way if any exist.

Here is my actual test.

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"

)

);

I think that it is a bit long for a test, and I would like to find a way to improve this. Do you have any solution?

Thanks for any help

网友答案:

You have to define how your datastructure should look. At the moment you have all this information scattered in your test statements. That makes it very ugly as you allready figured. What i like to do is to have some datastructure, that i can fill with data, that i am expecting. Then i can use this, to test, whether my data is valid or not. An example:

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;
}

A:

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

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

B:

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;
    }
}

Sorry for the code beeing so long. Hope you get the idea. Whether this is more elegant or not is up to you to decide.

相关阅读:
Top