4.6 Object Interactions


4.6 Object Interactions

One important feature of object-oriented programs is that the actual behavior of the system is determined by the interplay of many instances and not by single objects. However, classic unit tests are limited to checking the isolated behavior of a program unit, moving the test of the units' interplay to the so-called integration tests. Procedural integration tests focus on the syntactically correct use of the interfaces and verification of side effects. Today, these tasks are assumed by modern IDEs or data encapsulation, respectively. For this reason, McGregor and Sykes [McGregor01] suggest the new term interaction test to emphasize the shift of the test focus to the interplay of objects.

McGregor and Sykes distinguish between two main types of interaction tests:

  • Testing collection classes: They use the term collection class for any class that stores references to other objects—normally as 1:n relationships— without "collaborating," or using their services. Such a test involves only the addition, creation and removal, or deletion of referenced instances. A small (incomplete) test suite for an imaginary collection that takes String objects could look like this:

     public class MyCollectionTest extends TestCase {    ...    private MyCollection collection;    protected void setUp() {       collection = new MyCollection();    }    public void testAddString() {       assertTrue(collection.isEmpty());       assertEquals(0, collection.size());       assertFalse(collection.containsString("string1"));       collection.addString("string1");       assertFalse(collection.isEmpty());       assertEquals(1, collection.size());       assertTrue(collection.containsString("string1"));       collection.addString("string2");       assertFalse(collection.isEmpty());       assertEquals(2, collection.size());       assertTrue(collection.containsString("string2"));    }    public void testRemoveString() {       collection.addString("string1");       collection.addString("string2");       collection.addString("string3");       assertTrue(collection.containsString("string2"));       collection.removeString("string2");       assertFalse(collection.containsString("string2"));       assertEquals(2, collection.size());       collection.removeString("string3");       collection.removeString("string1");       assertTrue(collection.isEmpty());       assertEquals(0, collection.size());    } } 

    Depending on the type of collection and the desired error behavior, various test cases have to be added. The important thing is that no messages have to be sent to the "collected" instances for testing.

  • Testing collaborating classes: A class is called collaborating when it uses the services of other classes to meet its tasks, for example, when objects of the Dictionary class use an instance of DictionaryParser. The cooperation of objects can be either unidirectional or bidirectional; in other words, two objects can exchange messages in either direction.

    There is no general approach to test collaborations. We have already seen several examples, including all test cases of the DictionaryTest class with fromReader in their names, and we will see more later on. The important thing here is that we want to test the direct exchange of messages between neighboring objects. The more mediator objects exist between our "collaborators," the more difficult it becomes to control the tests and the more often we will come up against the phenomenon of swallowed errors described in the next section. And we should limit ourselves to the public interface of the called object in our collaboration, or we will run the risk of designing very modification-sensitive tests.

Although interaction tests are no longer unit tests on a class level, they are still indispensable for the correct behavior of our larger units. Experiences gained with object-oriented systems in the testing community contradict the hope that the correct interplay of our objects can be ensured solely by acceptance tests on a system level. When the distance between the test interface and the tested class becomes too big, too many errors in the components no longer reach the surface; they will be "hidden," but can still come up again under slightly modified circumstances.

For this reason, as developer-testers we won't be able to avoid different types of interaction tests. [9] Indeed, several of our previous test efforts were oriented to the interplay of two objects. The fact that interaction tests are important parts of a test suite should not tempt us to test some objects only indirectly through other collaborating objects. On the other hand, testing a class in isolation is not sufficient to check the interplay of objects. We always have to keep an eye on the drawbacks inherent in inter-unit tests: increased cost of changes and refactorings.

[9]For this reason, there are also proposals to rename XP unit tests mobility tests or build tests.




Unit Testing in Java. How Tests Drive the Code
Unit Testing in Java: How Tests Drive the Code (The Morgan Kaufmann Series in Software Engineering and Programming)
ISBN: 1558608680
EAN: 2147483647
Year: 2003
Pages: 144
Authors: Johannes Link

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net