2

Sorry for the long title, but my problem is as follows;

I have these classes;

public class A {
    int a1;
    int a2;
    List<B> listOfB;
}

and

public class B {
    int b1;
    int b2;
    List<C> listOfC;
}

and

public class C {
    int c1;
    int c2;
}

If it were only for B to assert the list of C it has, I would use the following custom matcher; Matcher<Iterable<C>> cMatcher = Matchers.hasItems(allOf(hasProperty("c1", equalTo(c1)), hasProperty("c2", equalTo(c2))))

But how can I do the assertion from A? I want to use this C list matcher in a larger scope matcher that does the following;

Matchers.hasItems(allOf(hasProperty("b1", equalTo(b1)), hasProperty("b2", equalTo(b2)), hasProperty("listOfC", cMatcher)))

So in a way I wish to match a B in listOfB where has given b1, and b2 values, together with its listOfC containing a specific C with values c1 and c2.

buræquete
  • 14,226
  • 4
  • 44
  • 89

3 Answers3

0

Whilst you could create a composite Hamcrest matcher, the difficulties you are facing outline a drawback in your testing approach.

The Law of Demeter suggests that you bound the testing to each class and not beyond.

That A has a correct list of B is fine, but how those Cs behave is entirely up to B and would belong in its tests.

buræquete
  • 14,226
  • 4
  • 44
  • 89
declension
  • 4,110
  • 22
  • 25
  • I agree, but the classes I am talking about is in the response object of the main method of the class that I am actually testing. The structure of these `A`, `B`, and `C` classes are out of my reach. – buræquete Feb 23 '16 at 08:53
0

Sorry to answer my own question, but the code I gave at the end was correct. There were some problems with the matcher constraints of the inner list C.

So to match a list in a list;

Matcher<Iterable<C>> cMatcher = Matchers.hasItems(allOf(hasProperty("c1", equalTo(c1)), hasProperty("c2", equalTo(c2))))

Then use this in the higher scope matcher;

Matchers.hasItems(allOf(hasProperty("b1", equalTo(b1)), hasProperty("b2", equalTo(b2)), hasProperty("listOfC", cMatcher)))

will match for the case I have described in my question.

The problem I have encountered is a field in my C class, which has type of Boolean, somehow hasProperty("boolField", true) does not match, saying property "boolField" is not readable. Probably due to the getter method of Boolean hasn't got a get prefix, in this question, it says primitive boolean works, while Boolean object fails in this situation

Community
  • 1
  • 1
buræquete
  • 14,226
  • 4
  • 44
  • 89
0

hasItems does partial match. Use containsInAnyOrder for exact match.

http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html

z atef
  • 7,138
  • 3
  • 55
  • 50