Over a million developers have joined DZone.

TDD: Combining the when and then steps

DZone's Guide to

TDD: Combining the when and then steps

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

I've written before about my favoured approach of writing tests in such a way that they have clear 'Given/When/Then' sections and something which I come across quite frequently is tests where the latter steps have been combined into one method call which takes care of both of these.

An example of this which I came across recently was roughly like this:

public void shouldCalculatePercentageDifferences() {
	verifyPercentage(50, 100, 100);
	verifyPercentage(100, 100, 0);
	verifyPercentage(100, 50, -50);
private void verifyPercentage(int originalValue, int newValue, int expectedValue) {
assertEquals(expectedValue, new PercentageCalculator().calculatePercentage(originalValue, newValue));

This code is certainly adhering to the DRY principle although it took us quite a while to work out what the different numbers being passed into 'verifyPercentage' were supposed to represent.

With this type of test I think it makes more sense to have a bit of duplication to make it easier for us to understand the test.

We changed this test to have its assertions inline and make use of the Hamcrest library to do those assertions:

public void shouldCalculatePercentageDifferences() {
assertThat(new PercentageCalculator().calculatePercentage(50, 100), is(100));
assertThat(new PercentageCalculator().calculatePercentage(100, 100), is(0));
assertThat(new PercentageCalculator().calculatePercentage(100, 50), is(-50));

I think we may have also created a field to instantiate 'PercentageCalculator' so that we didn't have to instantiate that three times.

Although we end up writing more code than in the first example I don't think it's a problem because it's now easier to understand and we'll be able to resolve any failures more quickly than we were able to previously.

As Michael Feathers points out during Jay Fields' 'Beta Test' presentation we need to remember why we try and adhere to the DRY principle in the first place.

To paraphrase his comments:

In production code if we don't adhere to the DRY principle then we might make a change to a piece of code and we won't know if there's another place where we need to make a change as well.

In test code the tests always tell us where we need to make changes because the tests will break.

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.


Published at DZone with permission of Mark Needham, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}