Testing Simple Getters and Setters

The bootstrapping dilemma applies equally to testing setters and getters, but the strategy presented in the previous section gives us a plan of attack. The encapsulation of the attributes prevents us from verifying the actions of the mutators without invoking the getters. It also inhibits us from setting the attributes to request through the getters without using the setters. Therefore, we are left with using getters to test setters and vice versa, effectively testing them together as shown in Listing 6-3.

Listing 6-3: Testing setters and getters together

1 public void testSetGetAttribute() {
2   MyObject sut = new MyObject();
3   assertNotNull(sut);
4   int expectedValue = 17;
5   assertThat(sut.getAttribute(),
        is(not(equalTo(expectedValue))));

6   sut.setAttribute(expectedValue);
7   int actualValue = sut.getAttribute();

8   assertEquals(expectedValue, actualValue);
9 }

First, note that the blank lines in the code divide the test into the sections of a Four-Phase Test [xTP] or, alternatively, the arrange-act-assert pattern. I find that explicitly delineating the phases where possible aids the clarity and legibility of the test. Even the introduction of the technically unnecessary intermediate variable actualValue assists in demarcating the phases and enhances the understanding of the intent.

The missing fourth phase is Garbage-Collected Teardown [xTP]. I highlight this because we need to be conscious of our teardown, even when the runtime does it for us. The prevalence of garbage-collected languages has simplified our code significantly by eliminating most of the overhead of explicit memory management. However, the corresponding removal of destructors has complicated the management of nonmemory resources—such as file handles and threads—at scope boundaries. In tests this applies to the clean up tasks we need to do at the end of the test for things that do not apply to all tests in a suite.

The use of assertions at lines 3 and 5 reinforces our preconditions for the test. JUnit provides a variant called an assumption, but it merely invalidates the test, treating it as if it were ignored. While this does not run a test whose preconditions have not been met, it also does not highlight that fact very strongly, so I will use assertions for this purpose instead.

Line 5 uses the more literate and declarative form embodied in Java by the Hamcrest matchers.2 Notice how the statement of our assumption reads very naturally in a way that can be otherwise difficult in many xUnit variants with the absence of assertNotEquals().

2. The Hamcrest matchers can be found at http://code.google.com/p/hamcrest/ and have been ported to several languages. They are included in the more recent versions of JUnit. Similar support for literate assertions is available for other frameworks.

In the execution phase of the test, we invoke both the setter and the getter, accounting for the name of the test method even to the ordering of the verbs. We finish up with a standard equality assertion in the verification phase.

With these two tests in place, the verification of the constructor and of the setter and getter, we have “proven” that the basic foundation for the functionality of the unit under test is sound and consistent. This provides the basis upon which we will build the remainder of the verification of our class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.189.67