开发者

What's the best way to use hamcrest-AS3 to test for membership in an IList?

开发者 https://www.devze.com 2023-01-01 15:40 出处:网络
I\'m using Flex 3.3开发者_运维百科, with hamcrest-as3 used to test for item membership in a list as part of my unit tests:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消