xingyixun / hamcrest

Automatically exported from code.google.com/p/hamcrest
0 stars 0 forks source link

Making assertions about Iterables #58

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I'm trying to test a method that returns an Iterable<SomeObject>. The way I
wanted to write my test was 

       Iterable<Element> expected = ...
       Iterable<Element> actual = ...
       assertThat(actual,   
both(contains(expected)).and(iterableWithSize(1)));

But this doesn't work because IsIterableContainingInOrder has contains
methods that take vargargs or up to six individual elements, but not one
that takes an iterable of items.  The solution is to change actual to be an
Element[] but it would be nice to be actually compare two Iterables rather
than an Iterable and an array.

Next problem I ran into was that the iterableWithSize(int) always returns
Iterable<Object> and so causes a compilation error.  We need someway to fix
the return type of iterableWithSize(int), maybe by doing something like
iterableOf(Element.class).withSize(int).

I ran into a similar problem with the emptyIterable() Matcher, it always
returns an Iterable<Object> so has to be used as
Matchers.<Element>emptyIterable(). I'm not sure of the best way to handle
that, but something like emptyIterable().of(Element.class) would be nice.

Original issue reported on code.google.com by rwallace...@gmail.com on 1 Jan 2009 at 5:05

GoogleCodeExporter commented 9 years ago
Yes, the overrides are a mess, largely thanks to broken Java generics, but it 
looks to me like there's a varargs 
version.

Also, remember that contains() will expect there to be the same number of 
matchers as items in the collection, 
so you don't need the second matcher.

Check the latest drop for iterableWithSize. It should have better generics. 
That said, I sometimes end up writing 
helper methods around an expectation to force the type.

Original comment by smgfree...@gmail.com on 28 Feb 2009 at 11:32

GoogleCodeExporter commented 9 years ago
iterableWithSize also caused problems for me, but I was able to use hasSize 
instead.

Note that hasSize works on Collection instead of Iterable, but this was not a 
problem for me.

Original comment by pjvleeu...@gmail.com on 25 Oct 2010 at 1:42

GoogleCodeExporter commented 9 years ago
tagging

Original comment by t.denley on 12 May 2012 at 11:01

GoogleCodeExporter commented 9 years ago
Same problem here:

Iterable<Foo> result = …
assertThat(result, is(iterableOfSize(2))); <- compile error

Shouldn't iterableOfSize(…) return a Matcher<? extends Object> instead of 
Matcher<Object>?

Original comment by oliver.gierke@me.com on 19 Jul 2012 at 7:11

GoogleCodeExporter commented 9 years ago
It's clunky but the following will compile and work

assertThat(result, IsIterableWithSize.<Foo>iterableWithSize(2));

See also 
http://stackoverflow.com/questions/9707531/hamcrest-generics-hell-2-iterablewith
size-gives-errror-is-not-applicable-for

Original comment by crottype...@gmail.com on 31 Jan 2013 at 7:09

GoogleCodeExporter commented 9 years ago
Correction:
assertThat(result, IsIterableWithSize.<Foo>iterableWithSize(2)); works in 
eclipse but not necessarily elsewhere!

Original comment by crottype...@gmail.com on 31 Jan 2013 at 7:50

GoogleCodeExporter commented 9 years ago
@Oliver this is working for me. Note that I am not using 
org.junit.Assert.assertThat. I had to bring hamcrest before junit in my eclipse 
classpath to achieve this. I am not sure on the details of how maven handles 
this.

    @Test
    public void test() {
        Foo foo = new Foo();
        Iterable<Foo> result = Arrays.asList(foo, foo);
        org.hamcrest.MatcherAssert.assertThat(result, org.hamcrest.Matchers.is(org.hamcrest.Matchers.<Foo> iterableWithSize(2)));
    }

Fully qualified because it matters what the external classes are!

Original comment by crottype...@gmail.com on 15 Mar 2013 at 12:46