What's the best way to use hamcrest-AS3 to test for membership in an IList?
I'm using Flex 3.3开发者_运维百科, with hamcrest-as3 used to test for item membership in a list as part of my unit tests:
var myList: IList = new ArrayCollection(['a', 'b', 'c']).list;
assertThat(myList, hasItems('a', 'b', 'c'));
The problem is that apparently the IList
class doesn't support for each
iteration; for example, with the above list, this will not trace anything:
for each (var i: * in myList) { trace (i); }
However, tracing either an Array
or an ArrayCollection
containing the same data will work just fine.
What I want to do is (without having to tear apart my existing IList
-based interface) be able to treat an IList
like an Array
or an ArrayCollection
for the purposes of testing, because that's what hamcrest does:
override public function matches(collection:Object):Boolean
{
for each (var item:Object in collection)
{
if (_elementMatcher.matches(item))
{
return true;
}
}
return false;
}
Is this simply doomed to failure? As a side note, why would the IList interface not be amenable to iteration this way? That just seems wrong.
You will have to create a custom Matcher
that's able to iterate over an IList
. More specifically, extend and override the matches method of IsArrayContainingMatcher
that you reference above (and you'll probably want to create IList
specific versions of hasItem
and hasItems
as well). A bit of a pain, but perhaps it's worth it to you.
Longer term, you could file an issue with hamcrest-as3 (or fork) to have array iteration abstracted using the Iterator pattern. The right Iterator could then be chosen automatically for the common types (Proxy
-subclasses, IList
) with perhaps an optional parameter to supply a custom Iterator.
For the main issue: Instead of passing the ArrayCollection.list to assertThat()
, pass the ArrayCollection itself. ArrayCollection implements IList and is iterable with for each
.
var myList:IList = new ArrayCollection(['a', 'b', 'c']);
assertThat(myList, hasItems('a', 'b', 'c'));
In answer to part two: ArrayCollection.list is an instance of ArrayList which does not extend Proxy and does not implement the required methods in order to iterate with for each
. ArrayCollection extends ListCollectionView which does extends Proxy and implements the required methods.
HTH.
I find myself coming back to this every once in a while. Rather than writing new Matchers, I find that the easiest solution is always to just call toArray() on the IList and match against the resulting array.
精彩评论