Class IteratorTester<E>
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:
- remove();
- hasNext()
- hasNext();
- remove();
- next();
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()
.
The value you pass to the parameter steps
should be greater than the length of your
iterator, so that this class can check that your iterator behaves correctly when it is exhausted.
For example, to test Collections.unmodifiableList
's iterator:
List<String> expectedElements =
Arrays.asList("a", "b", "c", "d", "e");
List<String> actualElements =
Collections.unmodifiableList(
Arrays.asList("a", "b", "c", "d", "e"));
IteratorTester<String> iteratorTester =
new IteratorTester<String>(
6,
IteratorFeature.UNMODIFIABLE,
expectedElements,
IteratorTester.KnownOrder.KNOWN_ORDER) {
@Override
protected Iterator<String> newTargetIterator() {
return actualElements.iterator();
}
};
iteratorTester.test();
iteratorTester.testForEachRemaining();
Note: It is necessary to use IteratorTester.KnownOrder
as shown above, rather
than KnownOrder
directly, because otherwise the code cannot be compiled.
-
Nested Class Summary
Nested classes/interfaces inherited from class com.google.common.collect.testing.AbstractIteratorTester
AbstractIteratorTester.KnownOrder, AbstractIteratorTester.MultiExceptionListIterator, AbstractIteratorTester.Stimulus<E,
T extends Iterator<E>> -
Field Summary
Fields inherited from class com.google.common.collect.testing.AbstractIteratorTester
add, hasNext, hasPrevious, next, nextIndex, previous, previousIndex, remove, set
-
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
IteratorTester
(int steps, Iterable<? extends IteratorFeature> features, Iterable<E> expectedElements, AbstractIteratorTester.KnownOrder knownOrder) Creates an IteratorTester. -
Method Summary
Modifier and TypeMethodDescriptionprotected final Iterable
<AbstractIteratorTester.Stimulus<E, Iterator<E>>> I'd like to make this a parameter to the constructor, but I can't because the stimulus instances refer tothis
.Methods inherited from class com.google.common.collect.testing.AbstractIteratorTester
iteratorStimuli, listIteratorStimuli, newTargetIterator, test, testForEachRemaining, verify
-
Constructor Details
-
IteratorTester
protected IteratorTester(int steps, Iterable<? extends IteratorFeature> features, Iterable<E> expectedElements, AbstractIteratorTester.KnownOrder knownOrder) Creates an IteratorTester.- Parameters:
steps
- how many operations to test for each tested pair of iteratorsfeatures
- the features supported by the iterator
-
-
Method Details
-
getStimulusValues
Description copied from class:AbstractIteratorTester
I'd like to make this a parameter to the constructor, but I can't because the stimulus instances refer tothis
.- Specified by:
getStimulusValues
in classAbstractIteratorTester<E,
Iterator<E>>
-