@GwtCompatible public abstract class IteratorTester<E> extends Object
Iterator.next()
, Iterator.hasNext()
and Iterator.remove()
operations. This utility takes the brute-force approach of trying all
possible sequences of these operations, up to a given number of steps. So, if
the caller specifies to use n steps, a total of 3^n tests are
actually performed.
For instance, if steps is 5, one example sequence that will be tested is:
This particular order of operations may be unrealistic, and testing all 3^5 of them may be thought of as overkill; however, it's difficult to determine which proper subset of this massive set would be sufficient to expose any possible bug. Brute force is simpler.
To use this class the concrete subclass must implement the
AbstractIteratorTester.newTargetIterator()
method. This is because it's
impossible to test an Iterator without changing its state, so the tester
needs a steady supply of fresh Iterators.
If your iterator supports modification through remove()
, you may
wish to override the verify() method, which is called after
each sequence and is guaranteed to be called using the latest values
obtained from AbstractIteratorTester.newTargetIterator()
.
Modifier and Type | Class and Description |
---|---|
static class |
AbstractIteratorTester.KnownOrder |
Modifier | Constructor and Description |
---|---|
protected |
IteratorTester(int steps,
Iterable<? extends IteratorFeature> features,
Iterable<E> expectedElements,
AbstractIteratorTester.KnownOrder knownOrder)
Creates an IteratorTester.
|
Modifier and Type | Method and Description |
---|---|
protected Iterable<com.google.common.collect.testing.AbstractIteratorTester.Stimulus<E,Iterator<E>>> |
getStimulusValues()
I'd like to make this a parameter to the constructor, but I can't because
the stimulus instances refer to
this . |
void |
ignoreSunJavaBug6529795()
Don't verify iterator behavior on remove() after a call to next()
throws an exception.
|
protected abstract I |
newTargetIterator()
Returns a new target iterator each time it's called.
|
void |
stopTestingWhenAddThrowsException()
Don't verify iterator behavior after a call to add() throws an exception.
|
void |
test()
Executes the test.
|
protected void |
verify(List<E> elements)
Override this to verify anything after running a list of Stimuli.
|
protected IteratorTester(int steps, Iterable<? extends IteratorFeature> features, Iterable<E> expectedElements, AbstractIteratorTester.KnownOrder knownOrder)
steps
- how many operations to test for each tested pair of iteratorsfeatures
- the features supported by the iteratorprotected final Iterable<com.google.common.collect.testing.AbstractIteratorTester.Stimulus<E,Iterator<E>>> getStimulusValues()
this
.public void ignoreSunJavaBug6529795()
JDK 6 currently has a bug where some iterators get into a undefined state when next() throws a NoSuchElementException. The correct behavior is for remove() to remove the last element returned by next, even if a subsequent next() call threw an exception; however JDK 6's HashMap and related classes throw an IllegalStateException in this case.
Calling this method causes the iterator tester to skip testing any remove() in a stimulus sequence after the reference iterator throws an exception in next().
TODO: remove this once we're on 6u5, which has the fix.
public void stopTestingWhenAddThrowsException()
AbstractList's ListIterator implementation gets into a undefined state when add() throws an UnsupportedOperationException. Instead of leaving the iterator's position unmodified, it increments it, skipping an element or even moving past the end of the list.
Calling this method causes the iterator tester to skip testing in a stimulus sequence after the iterator under test throws an exception in add().
TODO: remove this once the behavior is fixed.
protected abstract I newTargetIterator()
protected void verify(List<E> elements)
For example, verify that calls to remove() actually removed the correct elements.
elements
- the expected elements passed to the constructor, as mutated
by remove()
, set()
, and add()
callspublic final void test()
Copyright © 2010-2014. All Rights Reserved.