It states:
- A collection implementation can throw an exception. The collection will stay unchanged and contains() will return false.
- The add method return value indicates if the collection changed as a result of the call. The collection will contain the element (based on equals()) but only if the collection changed the very instance will be part of the collection.
@Test
public void collectionAdd() {
for (Pair<Integer, List<Integer>> any : somePairs(integers(), lists(integers()))) {
Integer element = any.getFirst();
Collection<Integer> collection = any.getSecond();
boolean changedCollection = false;
boolean exceptionThrown = false;
try {
changedCollection = collection.add(element);
} catch (Exception e) {
assertException(e);
exceptionThrown = true;
}
assertTrue(collection.contains(element) != exceptionThrown);
assertTrue(changedCollection == containsInstance(collection,
element));
}
}
private void assertException(Exception e) {
assertTrue(e instanceof UnsupportedOperationException
|| e instanceof ClassCastException
|| e instanceof IllegalArgumentException
|| e instanceof IllegalStateException);
}
private boolean containsInstance(Collection<?> collection, Object element) {
for (Object e : collection) if (e == element) return true;
return false;
}
So in this way a specification can be provided of an interface some third party has to implement. It's then up to the implementer to provide a generator for the implementation besides the working code.
This has obviously some overlap with contract-driven development and the assertions facility. One interesting reuse of the characteristic could be to take an implementation that states it fulfills a given contract and monitor the behaviour of the implementation at run time (i.e. not while test time) and to report violations of the contract.
No comments:
Post a Comment