4.2. Converting requirements to Spock tests

Spock blocks embody the low-level mechanics of unit tests. You should also pay equal attention to the methods and classes that contain them. In large enterprise projects, organization and naming of unit tests play a crucial role in easy maintenance and effortless refactoring.

Spock also offers metadata that you can use to annotate your tests for extra clarity. The advantage that this metadata has over normal Java comments is that it can be extracted by reporting tools.

4.2.1. Explaining the feature examined in a Spock test

A unique characteristic of Spock test methods is the capability to name them by using full English sentences. This is a huge advantage for Spock tests because it makes reading tests so much easier (even for nontechnical colleagues).

I’ve used this technique since the first chapter and consider it a groundbreaking feature of Spock, compared to the status quo. The following listing provides an example.

Listing 4.15. Test method describes exactly what is being tested

It’s your job to make sure that this text is understandable (even out of context). Ideally, it should match the specifications given by business analysts. If you don’t have detailed specifications (and you should), the method name should describe what’s being tested in a nontechnical way.

The names of Spock methods will appear in test results and coverage reports, so always assume that somebody will read this text without having direct access to the code of the implementation.

4.2.2. Marking the class under test inside a Spock test

In most unit tests, initialization code prepares multiple classes and input data. The class that will be tested and evaluated has more importance than its collaborators, which are the classes that communicate with it, but not under test (either because they have their own tests or because they’re assumed to be correct).

To distinguish this special class, Spock offers the @Subject annotation, as shown is the next listing. In this example, the class under test is the Basket class.

Listing 4.16. Marking the class under test

In this simple example, it might be easy to understand that the Basket class is the one being tested (especially by looking at the when: and then: blocks), but in larger unit tests, the class under test might not be obvious.

At the time of writing, there’s no reporting tool that takes into account the @Subject annotation, but you should use it anyway to improve readability by other programmers. In current reporting tools, you can’t see which class is under test and you’re forced to look at the source code to identify it. Hopefully, this limitation will be amended soon by newer versions of test reporting tools.

4.2.3. Describing the Spock unit test as a whole

You now have multiple test methods (features in Spock terminology) and want to group them in a Groovy class. This class is a specification, as you can see in the following listing.

Listing 4.17. Writing a Spock specification

The class that contains all the test methods is a Groovy class that must extend spock.lang.Specification. This makes it a Spock test. The name of the class can be anything, but it’s good practice to end the name in Spec (for example, BasketWeightSpec). You can pick any ending you want, as long as it’s the same on all your Spock tests, because it makes it easier for the build system (e.g., Maven) to detect Spock tests.

For technical reasons, Spock can’t allow you to name the class with full English text like the test methods. To remedy this limitation, it instead offers the @Title annotation, which you can use to give a human-readable explanation of the features that make up this specification.

Naming .groovy files using the expected Java convention

Unlike Java, Groovy doesn’t require the name of the class and the name of the file on the disk to be the same. You can place the BasketWeightSpec class in a file called MyBasketWeightUnitTest.groovy if that’s what you want. For simplicity, I still urge you to use the Java convention because it makes navigating Spock tests much easier. Therefore, the BasketWeightSpec class should be placed in a file named BasketWeightedSpec.groovy.

As an extra bonus, Spock also offers the @Narrative annotation, which can provide even more text that describes what the test does, as shown in the following listing.

Listing 4.18. Writing a full Spock specification

This listing uses a Groovy multiline string that allows you to insert as many lines of text as you want (a feature that your business analysts might love). In Groovy, multiline strings need triple quotes.

Listing 4.18 also shows the application of the @Subject annotation on the whole class. If you find that all your test methods focus on the same class (which is the usual case), you can apply the @Subject annotation at the top of the Spock test instead of placing it multiple times in the test methods. The class under test is then used as an argument (no need to add the .class extension).

Notice that for brevity I omit the @Title and @Narrative annotations (and usually @Subject as well) in this book’s examples. You should always attempt to include them in your Spock tests. I tend to look at @Title and @Subject as a compulsory requirement for a Spock test. @Narrative is good to have, but not essential for all kinds of tests.

4.2.4. Revising our view of a Spock test

Because I started explaining Spock elements by using a bottom-up approach, now that we’ve reached the top, let’s see how to revise all parts of a Spock test, as shown in figure 4.12.

Figure 4.12. Blocks inside features (test methods) inside Specification (Groovy class)

A Spock test is a Groovy class that extends spock.lang.Specification. It should be marked with the @Title annotation to explain its purpose.

The Spock test contains one or more test methods (features in Spock terminology) that examine various aspects of the class under test. Test methods can be named directly with full English sentences. The class under test should be marked with the @Subject annotation, either in each test method individually or at the top of the specification.

Finally, each Spock feature (test method) is characterized by the Spock blocks it contains. The most basic structure is the given-when-then blocks that prepare the test, trigger the tested action, and examine the results.

This diagram is useful for our next topic: the lifecycle of a Spock specification.

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

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