2.2. Groovy Power assert as a replacement for JUnit asserts

With the def mystery solved, the second striking feature of Spock tests is the lack of assert statements for evaluating results. All JUnit tests end with one or more assert statements[6] that define the expected result of the computation. If the expected result doesn’t match the actual one, the test will fail. JUnit comes with an extensive API for assert statements, and it’s considered a good practice to create your own extensions, dealing with the business domain of your application.

6

Not having an assert (or verify) statement is a huge antipattern, because the test never fails.

I mentioned in the previous chapter that unlike JUnit, Spock doesn’t have assert methods. In this section, you’ll see how Spock deals with assertions and how they can help you in case of test failures. I’ll also continue with the general theme of this chapter: reducing the amount of code needed when using Groovy instead of Java.

2.2.1. Understanding how Groovy handles asserts

In theory, Groovy asserts function in a similar way to Java asserts. They expect a Boolean variable (or an expression that evaluates to a Boolean), evaluate it, and if it’s true, the assertion passes successfully. Spock runs assertions in the same way. If all assertions pass, the unit test succeeds.

In practice, however, Java is very strict regarding true/false. Only Boolean variables can be tested for assertions. Groovy takes a more relaxed[7] approach to this, allowing all objects to be treated as Booleans.

7

Or error-prone, if you wish. Some of the old C traps are now possible with Groovy as well (but not all).

Groovy treats all objects[8] as true unless

8

Closures are also “true.”

  • The object is an empty string.
  • The object is a null reference.
  • The object is the zero number.
  • The object is an empty collection (map, list, array, and so on).
  • The object is the false Boolean (obviously).
  • The object is a regex matcher that fails.

The following listing shows some examples, with Groovy assertions demonstrating the rules of Groovy true/false.

Listing 2.9. Groovy can convert everything to a Boolean

If you run the preceding example, all asserts evaluate to true, and the final line is printed in the console.

Groovy Truth

The way Groovy handles true/false statements (called Groovy truth in Groovy parlance) can be used in Spock to trim the assert statement into a shorter form instead of converting it explicitly to Boolean variables.

Fun with Groovy truth

This is valid Groovy code: boolean flag = -45. Even though this line doesn’t even compile in Java, in Groovy the number –45 is a nonzero number, and therefore the variable flag is now true.

The next listing presents a Spock example with both approaches, using both an explicit Boolean evaluation (Java) and automatic “casting” to true/false (Groovy). The class under test is a trivial string tokenizer that counts word occurrences.

Listing 2.10. Groovy truth used in Spock tests

As an exercise, locate examples in chapter 1 that don’t use Groovy truth rules in the assert statements and rewrite them now that you know that Groovy can convert everything to a Boolean variable.[9]

9

Groovy strings also get an additional toBoolean() method that treats only true, y, and 1 as true.

2.2.2. Using Groovy assertions in Spock tests

In the previous section, you saw how to use Groovy truth to simplify your assert statements. I admit that this is another feature that looks mainly like sugarcoating, and you might not be impressed by the amount of code reduced. This is understandable, but the advantage of Groovy assertions isn’t the application of Groovy truth rules.

The killer feature of Groovy (and therefore Spock) is the information it gives when an assert fails. You’ve seen some hints of this in chapter 1, using assertions that expect numbers (code listings 1.2 and 1.3). In complex expressions, Groovy shows all intermediate results. Figure 2.3 shows the Eclipse JUnit window in both cases, but you get similar output if you run your unit tests in the command line or any other compatible tool with JUnit.

Figure 2.3. Groovy assert shows much more information than a JUnit assert.

The magic of this feature is that it works with all objects and not just primitives. Groovy has no such distinction: everything is an object as far as Groovy is concerned.

What == means in Groovy

In Groovy, the == operator isn’t testing identity like Java. It calls the equals() method of the object. Identity in Groovy is handled by the is keyword. Thus object1.is(object2) is the Groovy way of testing identity. You should be aware of this difference if you use objects in both sides of the assert statement. (If you perform only simple assertions with scalar values—as you should—then this difference doesn’t matter.)

Figure 2.4 is a more complex example of a failed Groovy assert with lists. Again notice how Groovy shows all intermediate operations, whereas JUnit reports only the final result.

Figure 2.4. Groovy assert with lists compared to JUnit assert

A Groovy Power assert works for your own objects as well, as shown in figure 2.5.

Figure 2.5. Groovy assert with the Java class shown in listing 2.10

This Spock feature is crucial for continuous delivery environments. As a developer, you can understand exactly what goes wrong when a test fails. A well-configured build server keeps all the results from unit tests and provides reports for the failed ones. Because Groovy (and by extension Spock) shows you the running context, you can, in several cases, fix the bug right away instead of spending time with a debugger in order to reproduce it. For enterprise environments in which running an integration test is a lengthy process, this extra context for failing tests is a time-saver that can easily persuade any Java developer to switch from JUnit.

I’ll show you how to further enhance the output of Groovy Power asserts in chapter 4. For now, I’ll continue with some useful Groovy features that have helped me in several Spock tests.

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

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