Mocking and Stubbing - CORE TESTING WITH SPOCK - Java Testing with Spock, Version 6 (2015)

Java Testing with Spock, Version 6 (2015)

PART 2: CORE TESTING WITH SPOCK

Chapter 6. Mocking and Stubbing

In this chapter

· Quick introduction to fake collaborators

· Instructing Spock stubs with canned responses

· Verifying interactions with Spock mocks

· Verifying arguments or return values of the class under test.

I will start this chapter with a quick theory reminder behind mocks and stubs (terminology used by Spock). If you have never used them before in your unit tests, feel free to consult other external sources as well to complete your knowledge[53]. You may have already seen them as "test doubles" or "fake collaborators", so if you know the theory, you can skip ahead to section 6.2 in order to see the implementation of Spock for fake objects.

Fake collaborators are a way to isolate a single class with your exact input and output specification so that you can examine it under a well controlled environment.

I briefly hinted about the mocking/stubbing capabilities of Spock in chapter 3 and promised that I will show you much more when the time comes (i.e. now!). Unlike JUnit, Spock has native support for mocks and there is no need to add an external library to use this technique. The syntax for mocking and stubbing is much simpler compared to other mocking frameworks.

6.1 Fake collaborators

Let's say that you have a Java class in your application that shuts down a nuclear reactor when radiation levels from a sensor pass a critical threshold. You want to write a unit test for that class. It would not be realistic to bombard the real sensor with radiation just to see your unit test work. It is also not realistic to shut down the actual nuclear reactor whenever the unit test runs.

For a more run-of-the-mill example assume that your Java class sends a reminder email to a customer whenever an invoice isn't settled on time. It would be very hard to recreate a delayed payment in the unit test, and it would also be unrealistic to send a real email each time the unit test runs.

For cases like this you need to employ "Fake collaborators" in your unit test. You need to fake the way your class gets the current sensor values as well as the communication with the nuclear reactor and similarly you need to fake the delayed payment and the email server.

A fake collaborator is a special class that replaces a real class in order to make its behavior deterministic (i.e. pre-programmed). There is no technical limitation that ties fake classes with unit tests. It is just that unit tests are much more flexible if they employ the power of fake classes (which is the running theme of this chapter).

Figure 6.1 Using fake classes we can define our own sensor values and replace the real nuclear reactor with a fake one. We safely mimic any possible situation we want without affecting the real hardware.

6.1.1 How fake collaborators isolate a class in unit tests

In a real system (or in an integration test) if a bug shows up, it is not immediately clear which class or classes are responsible for it. In a unit test that contains only a real class (class B in figure 1.1) we can pre-program its collaborators with "correct" and "expected" answers. Thus, it is very easy to focus the unit test on how this single class works and make sure that it contains no bugs (at least on its own).

These fake collaborators are not real classes because:

· They implement only the methods needed for the unit test and nothing else.

· When they make requests to the real class, the request parameters are pre-preprogrammed and known in advance.

· When they answer requests from the real class their answer is also pre-programmed.

The thing to remember is that only the programmer knows the existence of the fake classes. From the point of view of the real class everything is running normally. The real class thinks that it runs on a live system (because the fake classes still implement the agreed interfaces) without understanding that the whole stage is a single unit test.

For the rest of this chapter I will use the terms Stub and Mock for this type of fake classes, simply because this the terminology used also by Spock.

6.1.2 Faking classes in Spock: Mocks and Stubs

Mocks and stubs are a further subdivision of fake objects. Here is the definition I first introduced in Chapter 3.

1. A Stub is a fake class that comes with preprogrammed return values. It is injected in the class under test so that you have absolute control on what is being tested as input. In figure 6.1 the fake sensor is a Stub so that we can re-create any radiation levels we want.

2. A Mock is a fake class that can be examined after the test is finished for its interactions with the class under test (e.g. you can ask it if a method was called or how many times it was called). In figure 6.1 the fake reactor class is a Mock so that we ask it if its shutdown() method was called or not after the unit test has ended.

In practice, because Mocks can also be stubbed, you can think of them as a superset of Stubs (which themselves cannot be used for verification of interactions). In theory you could write all your Spock tests using only Mocks. For readability reasons it is best to decide in advance what type of fake object you are creating.

Unit testing and Film Making analogy

If you still have trouble understanding the difference between mocks and stubs, you can think that instead of a programmer, you are a film director. You want to shoot a scene (create a unit test). First you setup the actors, camera and sound that will create the illusion of the scene (i.e. you prepare stubs and mocks). You let the camera roll (i.e. run the unit test) and check the camera screen for the result (i.e. examine the test result).

Stubs are your sound technician, your lighting experts and your camera man. You give them instructions before each scene as you pre-program your stubs. They are essential for filming your scene, as stubs are essential for the correct functionality of your class under test. But they do not appear on the recorded scene, as stubs are never used for test verification.

Mocks are your actors. You also give them a script before the scene for their dialog, in the same way that you prepare your mocks (for their interaction with the class under test). After filming is finished, you check their on-screen performance as you check the interactions of your mocks.

Under dire circumstances you can force an actor to hold the boom microphone or the camera (i.e. use a Mock in place of a Stub) but you can never create an actor out of a technician on the spot (i.e. you cannot use a Stub for interaction verification).

6.1.3 When to use Mocks and Stubs

Knowing how to mock classes is not enough for effective unit tests. You also need to know which classes to mock out of all the collaborators. In a large enterprise project your class under test might interface with several other classes. You should ask yourself which classes need mocking and which classes can use their real implementation[54].

I have seen both sides of the spectrum where developers do not use mocking at all, making all unit tests run as integration tests. I have also seen excessive mocking of classes that do not need it. The former situation is not desirable because all tests will be slow and complex. The latter situation has its own problems as well. Upgrading badly designed mocked tests is very difficult when the production code changes because of unforeseen business requirements.

As a general rule of thumb you should mock/stub all collaborator classes that:

· make the unit test non-deterministic

· have severe side effects

· make the test depend on the computation environment

· make the test slow

· need to exhibit strange behavior normally not found on a real system.

The first case is fairly obvious. If you are writing a unit test for a game that uses electronic dice, you cannot possibly use the real dice class in your unit test. Instead you mock it to make it return a particular number that fits your scenario.

The second case was demonstrated in chapter 3. If you have code that charges credit cards, prints documents, launches missiles or shuts down nuclear reactors you must mock it so that nothing bad happens when a unit test runs.

The third case is about creating reliable tests that always have the same behavior when they run either on the build server or a development workstation. Code that reads environment variables, external setting files or asks for user input should be mocked with the variables used in that specific scenario.

In large enterprise projects tests can be really slow. A common speedup technique is to mock out code that reads files, communicates with a database or contacts an external network service. This makes the test CPU bound instead of I/O bound so tests run at the maximum capacity of the processor.

Finally, you need to stub objects when you want to create a specific behavior that is very hard to reproduce with the real class. Common cases are emulating a full hard disk or a complete failure in the network.

The corollary of the list above, is that if you have a collaborator class that does not depend on external services, or the environment, does not perform I/O operations and is fast in its responses, then you can use it as is, in a unit test (i.e. with its real implementation).

The class under test is always a real class

I am always baffled by questions in Stack Overflow and other forums/mailing lists, where people have difficulties with mocking because they try to mock the class under test instead of its collaborators. There are some advanced unit tests that need this (I will show you Spies in chapter 8) but this technique is only for extreme corner cases of legacy code. In vanilla unit tests, the class under test is always a real class. Mocks are used for its collaborators only. And even then, not all collaborators need to be mocked.

6.1.4 A sample application for an electronic shop system.

The running example for this chapter will be an expanded version of the eshop system that you have seen in chapter 4. Figure 6.2 shows a high level overview of the system under test.

Figure 6.2 an extended eshop that has an inventory and charges credit cards

In this eshop the client can browse product pages and add them in an electronic basket as before. But when she/he checkouts two additional actions are performed. First the inventory is checked to verify that the products are indeed ready for dispatching. And secondly the credit card of the client is charged using an external pre-existing service (that is the responsibility or another company)

The Java skeleton for this eshop is shown in listing 6.1, and it is similar to the one introduced in chapter4.

Listing 6.1 Java skeleton code for the eshop

public class Product { #A private String name; private int price; private int weight; [...getters and setters..] }public class WarehouseInventory { #B public int isProductAvailable(String productName) { [...code redacted for brevity..] } public boolean isProductAvailable(String productName,int count) #C { [...code redacted for brevity..] } public boolean isEmpty() #D { [...code redacted for brevity..] } }public class Basket { #E public void addProduct(Product product) { #F addProduct(product, 1); } public void addProduct(Product product, int times) { [...code redacted for brevity..] } public int getProductTypesCount() { [...code redacted for brevity..] } public void setWarehouseInventory(WarehouseInventory #G warehouseInventory) { [...code redacted for brevity..] } public boolean canShipCompletely() { #H [...code redacted for brevity..] }}

#A Simple holder class for a product

#B Contains stocked products - We will stub this

#C Checks if a product is stocked

#D Quick check of product availability

#E Class under test

#F triggered from the UI

#G Setter injection

#H method that needs to be tested

Just by looking at figure 6.2 you can already guess which class we will stub and which class we will mock. The inventory class will be stubbed (so that we can define the stock levels of various products, regardless to the real warehouse) and the credit card system will be mocked (so that we do not charge real credit cards when a unit test runs).

I will use this sample application throughout the chapter for increasingly complex examples of Spock unit tests that contain Mocks and Stubs.

6.2 Controlling input to the class under test with Stubs

Now that you know the theory behind mocks and stubs and the system that we will test, let's see how you can use them in your Spock tests. I will start with Stubs which are simpler. You stub all collaborator classes that are used by your class under test, but are not otherwise tested themselves. Either they have their own unit tests or they are external libraries and frameworks that are assumed to work correctly.

In general your class under test makes requests to your stubs. You need to tell Spock what to do when any of the stubbed methods are called. By default Spock will not complain if a method is called that was not explicitly stubbed.

Therefore creating a stub is a two step process:

1. Showing Spock which class will not use its real implementation and instead will be Stubbed

2. Declaring what will happen when any of the stubbed methods are called by the class under test (i.e. what will be the return values)

6.2.1 Basic stubbing of return values

The first thing we want to test is the canShipCompletely() method of the basket from listing 6.1. This method returns true when all products selected by the customer are available in the warehouse and false in any other case.

We will stub the warehouse inventory so that we can emulate both cases, where the product is in stock, and when the product is not currently available.

How to use the code listings

You can find almost all code listings for this book at https://github.com/kkapelon/java-testing-with-spock .

For brevity reasons, the book sometimes will point you to the source code (especially for long listings). I tend to use the Eclipse IDE in my day-to-day work. If you did not already install Spock and Eclipse in chapter 2, you can find installation instructions in Appendix A.

The warehouse inventory is a concrete class that is used by the basket class during checkout. Imagine that this class is part of an external system that we don't have any control over. We don't want our unit tests to be based on the real inventory of this eshop. We need a way to trick the inventory to contain what we want for each business scenario that we test. A first example where we stub it is shown in listing 6.2

Listing 6.2 Creating a Simple Stub with Spock

def "If warehouse is empty nothing can be shipped"() { given: "a basket and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Basket basket = new Basket() and:"an empty warehouse" WarehouseInventory inventory = Stub(WarehouseInventory) #A inventory.isEmpty() >> true #B basket.setWarehouseInventory(inventory) #C when: "user checks out the tv" basket.addProduct tv then: "order cannot be shipped" !basket.canShipCompletely() #D}

#A Creates Spock Stub

#B Instructs the stub to return true when isEmpty() is called

#C Injects the stub into the class under test

#D Calls the Stub behind the scenes

The most important lines from listing 6.2 are the following:

WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isEmpty() >> true

The first line creates a Spock Stub that looks and "acts" as the class WarehouseInventory. However all methods that are called on this stub are intercepted automatically by Spock and never reach the real implementation.

The second line uses the right-shift operator. This is a special Spock operator (remember that Groovy allows for operator overloading unlike Java) and hardwires the isEmpty() method to return true regardless of the real implementation of the original class. Thus when the basket is asked to respond on the shipping status of the order it calls (behind the scenes) the stubbed method and gets a negative result from the inventory.

In order to stub a method for specific arguments you can use the right-shift operator directly on the method call you want to emulate as seen in listing 6.3:

Listing 6.3 Stubbing specific arguments

def "If warehouse has the product on stock everything is fine"() { given: "a basket and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Basket basket = new Basket() and:"a warehouse with enough stock" WarehouseInventory inventory = Stub(WarehouseInventory) #A inventory.isProductAvailable("bravia",1) >> true #B inventory.isEmpty() >> false #C basket.setWarehouseInventory(inventory) when: "user checks out the tv" basket.addProduct tv then: "order can be shipped right away" basket.canShipCompletely()}

#A Creation of a Spock Stub

#B Instructing the stub to return true when specific arguments are used

#C Instructing the warehouse to respond with false

Here we change the inventory to emulate the happy scenario where the product actually exists on the warehouse. It is also possible to differentiate method calls according to their arguments and stub them with different return results. This is demonstrated in listing 6.4

Listing 6.4 Argument based stub differentiation

def "If warehouse does not have all products, order cannot be shipped"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and:"a warehouse with partial availability" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable("bravia",1) >> true #A inventory.isProductAvailable("panasonic",1) >> false #A inventory.isEmpty() >> false basket.setWarehouseInventory(inventory) when: "user checks out both products" basket.addProduct tv basket.addProduct camera then: "order cannot be shipped right away" !basket.canShipCompletely()}

#A Different stub results depending on the argument

Finally, you can group all stubbing instructions in a single code block in a similar way to the with() method shown in chapter 4. The code shown in listing 6.5 behaves in exactly the same way as the one in 6.4 and only the syntax differs. You should decide for yourself which of the two you prefer.

Listing 6.5 Grouping all stubbed methods

def "If warehouse does not have all products, order cannot be shipped (alt)"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and:"a warehouse with partial availability" WarehouseInventory inventory = Stub(WarehouseInventory) { isProductAvailable("bravia",1) >> true #A isProductAvailable("panasonic",1) >> false #A isEmpty() >> false #A } basket.warehouseInventory = inventory when: "user checks out both products" basket.addProduct tv basket.addProduct camera then: "order cannot be shipped right away" !basket.canShipCompletely()}

#A Compact way of stubbing methods

#B Setter injection using Groovy style

Notice that in all the above code listings the real code of warehouse inventory never runs. The Spock unit tests shown, can run on their own regardless of the actual status of the real inventory. As long as the signature of the warehouse class stays the same (i.e. the method definitions) these unit tests will continue to run correctly even if new methods are added to the original class. Now you know how you can Stub classes in Spock!

6.2.2 Matching arguments leniently when a stubbed method is called

In the previous section I have shown you how to stub methods using the exact arguments you expect to be called. This works for trivial tests, but for bigger tests this precision is not always needed. For example if I wanted to create a unit test that involved ten different products, I would have to stub ten different calls for the same method.

A more practical solution is offered by Spock in the form of argument matchers when you do not really care for so much detail. The character Spock uses is the underscore (_) and in general it plays the role of "I do not really care what goes in here" depending on the context, (as you will see during the course of this chapter). Listing 6.6 shows the usage of the underscore as argument matcher.

Listing 6.6 Using argument matchers in stubs

def "If warehouse has both products everything is fine"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and:"a warehouse with enough stock" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable(_, 1) >> true #A basket.setWarehouseInventory(inventory) when: "user checks out the tv and the camera" basket.addProduct tv basket.addProduct camera then: "order can be shipped right away" basket.canShipCompletely()}

#A Stubbing a method call regardless of the value of an argument

Here I have stubbed the inventory method only once, and I know that it can be called for all products I ask it for, regardless of their name[55]. I have chosen this approach because in this particular test I am not interested in examining the correctness of the warehouse (the focus of the test is still the basket class).

It is also possible to use matchers for all arguments of a method, resulting in very powerful stubbing combinations. An example is shown in listing 6.7

Listing 6.7 Ignoring all arguments of a stubbed method when returning a response

def "If warehouse is fully stocked stock everything is fine"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and:"a warehouse with limitless stock" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable( _, _) >> true #A basket.setWarehouseInventory(inventory) when: "user checks out multiple products" basket.addProduct tv,33 #B basket.addProduct camera,12 #B then: "order can be shipped right away" basket.canShipCompletely()}

#A Stubbing a method for all its possible arguments

#B Both these calls will be matched

Here I have instructed my warehouse to answer that the product is always in stock, regardless of the actual product. I do not care if the class under test asks for a tv or a camera, they will always be in stock.

Stubbing a method regardless of its arguments is a very powerful technique that can be very helpful in large unit tests where the stub is just a secondary dependency which is outside the focus of the test. Dispatchers, delegates, facades, decorators and other design patterns are perfect candidates for this kind of stubbing as most times they get in the way of the class under test.

6.2.3 Sequential stubs with different responses for each method call

In listing 6.5 you have seen how you can differentiate the stub response based on the argument. This is one dimension of different responses. The other dimension is to stub different responses depending on the number of times a method is called.

This is accomplished with the unsigned right shift operator (>>>) which was actually introduced in chapter 3. Another example is shown below:

Listing 6.8 Stubbing subsequent method calls

def "Inventory is always checked in the last possible moment"() { given: "a basket and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Basket basket = new Basket() and:"a warehouse with fluctuating stock levels" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable( "bravia", _) >>> true >> false #A inventory.isEmpty() >>> [false, true] #B basket.setWarehouseInventory(inventory) when: "user checks out the tv" basket.addProduct tv then: "order can be shipped right away" basket.canShipCompletely() #C when: "user wants another TV" basket.addProduct tv then: "order can no longer be shipped" !basket.canShipCompletely() #D}

#A First call with return true and second will return false

#B Spock can also iterate on a collection for ordered responses

#C The inventory stub is called for the first time behind the scenes

#D The inventory stub is called a second time

The unsigned shift operator signifies to Spock that the expression following it will be used as a response for each subsequent calls of the exact same method. Multiple answers can be chained together using the normal shift operator >>.

An alternative syntax (and the one I also prefer) is to use a collection after the unsigned shift operator. Each item of the collection will be used in turn as a response when the stubbed method is called. As with parameterized tests, remember that Groovy has a more general idea of "iterable" things than Java, so you don't have to actually use a list as is shown in listing 6.8.

6.2.4 Throwing exceptions when a stubbed method is called

I said in the introduction of this chapter that stubs are essential if you want to emulate a hard-to-reproduce situation or a corner case that does not normally happen with production code. For large scale applications where the code that handles error conditions can easily outweigh the code for happy path scenarios, it is essential to create unit tests that trigger those error conditions.

In the most common case, the error conditions come in the form of Java exceptions. These can be easily emulated as shown in listing 6.9.

Listing 6.9 Instructing stubs to throw exceptions

def "A problematic inventory means nothing can be shipped"() { given: "a basket and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Basket basket = new Basket() and:"a warehouse with serious issues" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable( "bravia", _) >> { throw new RuntimeException("critical error") } #A basket.setWarehouseInventory(inventory) when: "user checks out the tv" basket.addProduct tv then: "order cannot be shipped" !basket.canShipCompletely() #B}

#A Stub is instructed to throw an exception

#B Makes sure that the basket class can recover from the exception

The basket class calls the warehouse class and if anything goes wrong (even in if an exception is thrown) the canShipCompletely() method recovers by simple returning false (while leaving the basket class in a valid state). To verify this capability of the basket class, we need to instruct the warehouse to throw an exception when the stubbed method is called.

We still use the right shift >> operator for stubbing but instead of returning a normal value like the previous examples, we can place any Java code inside the brackets (which in reality are a Groovy closure if you have been paying attention in Chapter 2).

Inside the brackets you can put any code with Java statements, so a very useful capability is to throw an exception. The beauty of Spock is that throwing exceptions is not something special that requires special syntax. Instead you are offered a generic way to do anything when a stubbed method is called and throwing an exception is just one possibility of the many.

The great power of using Groovy closures in Spock stubs will be revealed fully in the next section.

Closures - the Swiss army knife of Groovy

I briefly talked about Closures in chapter 2. In their simplest form you can think of them as more flexible anonymous Java functions. If you already worked with Java 8 and lamba expressions, then Groovy closures will be very familiar.

6.2.5 Dynamic stubs that check arguments when responding

In the previous section you have seen how you can throw an exception in a stub by using a Groovy closure. I consider Groovy closures a very powerful feature even in the presence of Java 8, because the way Groovy closures are used in Spock is really refreshing. In other mocking frameworks such as Mockito you need to learn separate syntax semantics for argument catchers, exception throwing and dynamic responses. In Spock all these are unified under Groovy closures.

Before I show you any code I will repeat the warning of chapter 2. If you don't feel yet comfortable with Groovy closures (or Java 8 lambda expressions) feel free to skip this section and come at a later point in time. Closures can also be used with mocks as you will see later in this chapter.

To make our example more interesting I will add another dependency to the basket class. This time it will be an interface (instead of a concrete class) as below:

public interface ShippingCalculator { int findShippingCostFor(Product product, int times);}

This interface is responsible for shipping charges. It accepts a product and the number of times it was added in the basket and returns the shipping costs (in whatever currency the eshop uses). The basket class is also augmented with a findTotalCost() method that calls the shipping calculator behind the scenes in order to add shipping charges to the product value. We want to test this new method of the basket class.

As a business scenario we choose a simple shipping strategy. For each product we add 10 dollars to the final cost for each time it is added to the basket regardless of product type[56]. A naive way of stubbing the shipping calculator would be the following:

ShippingCalculator shippingCalculator = Stub(ShippingCalculator)

shippingCalculator.findShippingCostFor(tv, 2) >> 20

shippingCalculator.findShippingCostFor(camera, 2) >> 20

shippingCalculator.findShippingCostFor(hifi, 1) >> 10

shippingCalculator.findShippingCostFor(laptop, 3) >> 30

Here I instruct the shipping module with specific responses according to the arguments of the called method. This code is not very readable and clearly suffers from verbosity. It will also be very hard to write unit tests with a large amount of products (imagine a unit test that added 100 products from an external source).

With the power of closures, Spock allows you to capture our simple pricing strategy with a single line of code! Code listing 6.10 demonstrates this technique and also shows that Spock can stub both interfaces and concrete classes in an agnostic way.

Listing 6.10 Stubs that respond according to arguments

def "Basket handles shipping charges according to product count"() { given: "a basket and several products" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Product hifi = new Product(name:"jvc",price:600,weight:5) Product laptop = new Product(name:"toshiba",price:800,weight:10) Basket basket = new Basket() and: "a fully stocked warehouse" WarehouseInventory inventory = Stub(WarehouseInventory) #A inventory.isProductAvailable( _ , _) >> true basket.setWarehouseInventory(inventory) and: "a shipping calculator that charges 10 dollars for each product" ShippingCalculator shippingCalculator = Stub(ShippingCalculator) #B shippingCalculator.findShippingCostFor( _, _) >> { Product product, int count -> 10 * count} #C basket.setShippingCalculator(shippingCalculator) when: "user checks out several products in different quantities" basket.addProduct tv, 2 #D basket.addProduct camera, 2 #D basket.addProduct hifi #D basket.addProduct laptop, 3 #D then: "cost is correctly calculated" basket.findTotalCost() == 2 * tv.price + 2 * camera.price + hifi.price + 3 * laptop.price + basket.getProductCount() * 10 #E}

#A Stubbing a concrete class

#B Stubbing a Java interface

#C Using a Groovy closure for a dynamic response

#D Adding to the basket different quantities

#E Verifying that shipping charges are included

Using the Groovy closure I have instrumented the shipping calculator stub with my selected pricing strategy in a single line of code. With that one line of code the shipping calculator can respond to 1,2 or 100 products added to the basket. Its behavior is no longer statically defined but it can understand its arguments.

For an even smarter stub, assume that the eshop sells also downloadable goods. For these, the shipping cost should obviously be zero. Again a naive way to cater for this case would be to instruct my stub with specific products to return 0 like:

shippingCalculator.findShippingCostFor(ebook, _) >> 0

Doing this would not be scalable because if a unit test examined 10 different downloadable goods I would have to manually stub the response 10 times. Remember that the interface for the shipping calculator also gives me access to the product, as well as the number of times it was added to the basket. Therefore I can modify the Groovy closure to look at both arguments:

Listing 6.11 A smart stub that looks at both its arguments

def "Downloadable goods do not have shipping cost"() { given: "a basket and several products" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Product hifi = new Product(name:"jvc",price:600,weight:5) Product laptop = new Product(name:"toshiba",price:800,weight:10) Product ebook = new Product(name:"learning exposure",price:30,weight:0) Product suite = new Product(name:"adobe essentials",price:200,weight:0) Basket basket = new Basket() and: "a fully stocked warehouse" WarehouseInventory inventory = Stub(WarehouseInventory) inventory.isProductAvailable( _ , _) >> true basket.setWarehouseInventory(inventory) and: "a shipping calculator that charges 10 dollars for each physical product" ShippingCalculator shippingCalculator = Stub(ShippingCalculator) #A shippingCalculator.findShippingCostFor( _, _) >> { Product product, int count -> product.weight==0 ? 0 :10 * count} #B basket.setShippingCalculator(shippingCalculator) when: "user checks out several products in different quantities" basket.addProduct tv,2 basket.addProduct camera,2 basket.addProduct hifi basket.addProduct laptop basket.addProduct ebook basket.addProduct suite,3 then: "cost is correctly calculated" basket.findTotalCost() == 2 * tv.price + 2 * camera.price + hifi.price + laptop.price + ebook.price + 3 * suite.price+ 60 #C}

#A Stubbing a Java interface

#B Groovy closure that uses both arguments

#C 60 is shipping charges for the physical goods only

Here I have managed to instruct the shipping calculator with a single Groovy code a different behavior for downloadable and physical products. If the product has zero weight then shipping costs are also free. In any other case the standard charge for 10 dollars/euros is returned.

Using Groovy closures for argument matching is a technique that can be easily abused. Only use it when you find that it adds in the scalability and readability of your Spock test. In simple tests you might get way with direct stubbing of all argument combinations if their number is manageable.

6.2.6 Returning Stubs from the responses of other stubs

Before leaving stubs and diving into mocks, it is worth demonstrating the fact that Spock supports "recursive stubbing". With this term I mean that it is possible to have stubs return stubs as responses, which themselves return stubs and so on until you get to actual values.

In well designed code (that uses correctly dependency injection) this technique is not normally needed. It becomes handy for legacy code and incorrectly designed enterprise codebases. To mimic legacy code let's assume that your basket class is actually this:

public class EnterprisyBasket{ public EnterprisyBasket(ServiceLocator serviceLocator) { setWarehouseInventory(serviceLocator.getWarehouseInventory()); } [...rest of implementation here...]}

Here the basket class is not injected directly with its dependencies but instead gets a Service Locator object which acts as an intermediary to the actual services needed. And here is its code:

public interface ServiceLocator { WarehouseInventory getWarehouseInventory(); [... other services here...]}

Spock can easily deal with this situation as seen below

Listing 6.12 Stubbing responses with other stubs

def "If warehouse is empty nothing can be shipped"() { given: "a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) and:"an empty warehouse" WarehouseInventory inventory = Stub(WarehouseInventory) #A inventory.isEmpty() >> true ServiceLocator serviceLocator = Stub(ServiceLocator) #B serviceLocator.getWarehouseInventory() >> inventory #C and: "a basket" EnterprisyBasket basket = new EnterprisyBasket(serviceLocator) #D when: "user checks out the tv" basket.addProduct tv then: "order cannot be shipped" !basket.canShipCompletely()}

#A Stub that will be used by the class under test

#B Stubbing of intermediary class

#C Instructing a stub to return another stub

#D Using the parent stub in the class under test

In the example of listing 6.12 I have used only two levels of stubs, but it is perfectly possible to use more if your legacy code requires it.

6.3 Mocks: verifying values returned from the class under test

Stubs are great when your class under test already has methods that allow you to understand if everything works as expected (such as the canShipCompletely() method of the basket class). But most of the times the only way to understand what happened during the unit test is to have a "log" of what methods were called along with their arguments and their responses.

Mocks are the answer to this need. By mocking a collaborator of the class under test, not only you can pre-program it with canned responses but you can also query it (after the unit test has finished) about all its interactions.

Spock has a huge range of options when it comes to Mocks

Spock supports many different features when it comes to mocking. Some are more useful than others, some only apply to extreme cases and some are even so confusing that I specifically avoid on purpose. In this chapter I will show you the features I personally find useful (I have left out about 10% of Spock features). You can always consult the official Spock web site as a reference documentation.

6.3.1 All capabilities of Stubs exists in Mocks as well

The first thing to get out of the way is that Mocks are a superset of Stubs. All code listings I have shown you so far will work even if you use a mock. As a matter of fact here is listing 6.2 written with a Mock this time. Apart from a single line the rest of the code is exactly the same.

Listing 6.13 Mocks can be stubbed too

def "If warehouse is empty nothing can be shipped"() { given: "a basket and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Basket basket = new Basket() and:"an empty warehouse" WarehouseInventory inventory = Mock(WarehouseInventory) #A inventory.isEmpty() >> true #B basket.setWarehouseInventory(inventory) #C when: "user checks out the tv" basket.addProduct tv then: "order cannot be shipped" !basket.canShipCompletely() #D}

#A Creation of a Mock

#B Instructing the mock to return true when isEmpty() is called

#C Inject the mock into the class under test

#D This method calls the Mock behind the scenes

In Spock, you use stubs when you want to denote that the fake class you are going to use will only come with preprogrammed behavior and its interactions will not be verified. Out of the two listings the semantically correct is 6.2 (with the stub) because the warehouse inventory is never queried at the end of the unit test for its interactions with the Basket class.

Spock enforces this convention, so while Mocks will work in the place of Stubs, the opposite does not apply. Attempting to use a Stub in place of a Mock (the code listings in the next sections) will throw an error when Spock runs the unit test.

6.3.2 Simple mocking - examining if a method was called

Let's add another collaborator class in our electronic basket example. This time we will add the capability of charging credit cards.

Listing 6.14 Java skeleton for credit card charging

public class Customer { #A private String name; private boolean vip = false; private String creditCard; #B [...getters and setters here...]}public enum CreditCardResult { OK, INVALID_CARD, NOT_ENOUGH_FUNDS; #C }public interface CreditCardProcessor { #D CreditCardResult sale(int amount, Customer customer); #E void shutdown(); #F}public class BillableBasket extends Basket{ private CreditCardProcessor creditCardProcessor; public void setCreditCardProcessor(CreditCardProcessor #G creditCardProcessor) { this.creditCardProcessor = creditCardProcessor; } public void checkout(Customer customer) #H { [...code redacted..] } }

#A Simple object for customer

#B Credit card number

#C Possible results from charging a credit card

#D Interface provided by an external system

#E Charging method

#F Must be called after each charge

#G Setter injection

#H Triggers credit card injection

The credit card system is implemented by an external library (imagine that you do not even have the source code) . Reading its API documentation you see a big warning where its developers explain that the shutdown() method MUST be called whenever a credit card charge happens[57].

Your job is to write a unit test that verifies the call of this method by the basket class without actually charging a credit card. You could get away with a stub, if the credit card processor had a method namedshutdownWasCalled()! But it doesn't!

You can use a Mock, instead of a pure stub as below:

Listing 6.15 Verification of a mocked method

def "credit card connection is always closed down"() { given: "a basket, a customer and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false, creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) #A basket.setCreditCardProcessor(creditCardSevice) #B when: "user checks out the tv" basket.addProduct tv basket.checkout(customer) #C then: "connection is always closed at the end" 1 * creditCardSevice.shutdown() #D}

#A Creation of a Mock from an interface

#B Injecting the mock into the class under test

#C This method calls the Mock behind the scenes

#D Verifying called method

The important code line of this listing is the last one. Unlike all previous Spock tests it does not contain a normal assert statement (that is checked according to Groovy truth). This line is special Spock syntax and comes in the format:

N * mockObject.method(arguments)

When Spock sees this line it makes the test pass only if that method on the mock has been called N times with the arguments provided (which can also be argument matchers as with stubs).

The last line in listing 6.15 means "after this test is finished I expect that the number of times the shutdown () method was called is once". The test will pass if this sentence is true and fail in any other case.

Assume that with that unit test in place, a developer introduces a bug in the basket class that calls the shutdown method two times. Spock will instantly fail the test with the following error message:

Figure 6.3 Spock fails the test when the mocked method was called twice

Spock knows the exact invocations of all mocks, because during the test it has replaced the classes with its own proxies that record everything.

6.3.3 Verifying order of interactions

With the mock for the credit card processor in place we can ensure that the credit card service is indeed shut down after the transaction (and without actually charging a real credit card). However listing 6.13 misses the sequence of calls. How do we know that the shutdown() method is called really at the end, and not before the credit card charge step (which would be an obvious bug)? Listing 6.13 does not cover this scenario.

Your first impulse to check the order of calls that happen with the credit card service would be to write something like this:

then: "credit card is charged and CC service is closed down"1 * creditCardSevice.sale(1200,customer)1 * creditCardSevice.shutdown()

This will NOT work as expected. Spock does not pay any attention to the order of verifications inside a specific then: block. The unit test above will always pass regardless of the exact sequence of events (if both of them are correct on their own)

The correct unit test needs to exploit the fact that multiple then: blocks are checked in order by Spock[58] as shown below:

Listing 6.16 Verification of a specific order of mocked methods

def "credit card connection is closed down in the end"() { given: "a basket, a customer and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false, creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) #A basket.setCreditCardProcessor(creditCardSevice) when: "user checks out the tv" basket.addProduct tv basket.checkout(customer) then: "credit card is charged and" #B 1 * creditCardSevice.sale( _, _) #B then: "the credit card service is closed down" #C 1 * creditCardSevice.shutdown() #C}

#A Creation of a Mock from an interface

#B First this verification will be checked

#C Only if the first verification passes, this will be checked

Notice also that in this particular test we want to focus on the order of events and nothing else, so I have used unconditional argument matchers for the arguments of the sale() method because I do not really care about them in this test (Normally there should be another unit test focusing on them).

6.3.4 Verifying number of method calls of the mocked class

If you have already significant experience with other mocking frameworks[59] you should have noticed something strange between listings 6.13 and 6.14. In the latter case I have clearly noted to Spock that I expect the sale()method to be called. However listing 6.13 mentions nothing about the sale() method. How does the test in listing 6.13 pass?

It turns out that mocks and stubs created by Spock are lenient by default. The test will fail, only if the behavior of the mocks is against your explicit instructions contained in the then: block. Calling a method of a mock that was never mentioned has no negative effect. Not-calling a stubbed/mocked method also does not affect the unit test.

When you call a mocked method that does not have explicit stubbing instructions, Spock will return default values (false for Boolean variables, 0 for numbers and null for objects). If you want to make sure that a method is not called in a mock you have to declare it in the then: block as well. Pay close attention to the last statement of this code listing.

Listing 6.17 Explicit declaration of interactions

def "Warehouse is queried for each product"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and: "a warehouse with limitless stock" WarehouseInventory inventory = Mock(WarehouseInventory) #A basket.setWarehouseInventory(inventory) when: "user checks out both products" basket.addProduct tv basket.addProduct camera boolean readyToShip = basket.canShipCompletely() #B then: "order can be shipped" readyToShip #B 2 * inventory.isProductAvailable( _ , _) >> true #C 0 * inventory.preload(_ , _) #D}

#A Creation of a Mock/Stub

#B Mocks are only checks in the when: block

#C Stubbing a mocked method

#D Verifying that a method was never called.

There are three important points to notice in listing 6.17 that relate to the three lines in the then: block.

Starting from the bottom, we want to make sure that basket only queries the warehouse, but never tampers with the stock levels. Therefore I have explicitly stated that I expected zero invocations for the method the fills the inventory.

In the middle line I verify that the method of product availability is called twice (because the test deals with two products). Because I want the basket to think that the warehouse is full I also stub the method to return true both times. Thus the code in this line is both a mock expectation and a predefined stubbed response[60].

2 * inventory.isProductAvailable( _ , _) >> true

This line says to Spock "after this test is finished I expect that the method isProductAvailable() was called twice. I don't care about the arguments. But when it is called please return true to the class that called it".

The last thing to notice is that unlike previous code listings the canShipCompletely() method is called in the when: block and only its result is checked in the then: block. The reason for this is that Spock records the interactions of mocks in the when: block (which always should contain the trigger code). When using mocks, the then: block must contain only verifications.

6.3.5 Verifying non-interactions for multiple mocked classes

Now you know how to verify individual methods for any number of invocations. However, sometimes you want to cast a wider net, and control invocations at the class level instead of the method level. The underscore character is very flexible regarding its position inside a verification statement.

Listing 6.18 Verifying interactions for all methods of a class

def "Warehouse is queried for each product - strict"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and: "a warehouse with limitless stock" WarehouseInventory inventory = Mock(WarehouseInventory) basket.setWarehouseInventory(inventory) when: "user checks out both products" basket.addProduct tv basket.addProduct camera boolean readyToShip = basket.canShipCompletely() then: "order can be shipped" readyToShip 2 * inventory.isProductAvailable( _ , _) >> true #A 1 * inventory.isEmpty() >> false #A 0 * inventory._ #B}

#A Setting expectations for specific methods

#B Settings expectations for all other methods of the class

Here I have written a very strict unit test, because it assumes that regardless of the number of methods that exist in the inventory class, the basket class should call only isProductAvailable() and isEmpty() and nothing else. Therefore in the last verification line I use the underscore as a method matcher.

0 * inventory._

This line means "I expect zero invocations for all other methods of the inventory class". Be careful when using this technique because it means that you know exactly the interface between the class under test and the mock. If a new method is added in the mock (in the production code) which is used by the class under test, this Spock test will instantly fail.

You can write even stricter tests if you have multiple mocks if you place the underscore as a class name as shown below:

Listing 6.19 Verifying non-interactions for all mocks

def "Only warehouse is queried when checking shipping status"() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and: "a warehouse with limitless stock" WarehouseInventory inventory = Mock(WarehouseInventory) basket.setWarehouseInventory(inventory) ShippingCalculator shippingCalculator = Mock(ShippingCalculator) basket.setShippingCalculator(shippingCalculator) when: "user checks out both products" basket.addProduct tv basket.addProduct camera boolean readyToShip = basket.canShipCompletely() then: "order can be shipped" readyToShip 2 * inventory.isProductAvailable( _ , _) >> true #A _ * inventory.isEmpty() >> false #B 0 * _ #C}

#A Underscore matches arguments

#B Underscore matches number of invocations

#C Underscore matches mocked classes

In this code listing the basket class is injected with two mocks (one for shipping costs and one for the inventory). After running the test, I want to verify that only two specific methods were called on the inventory and nothing was called for the shipping cost service. Instead of manually declaring all other methods with zero cardinality one by one, I instead use the underscore character in the class part of the verification. The line

0 * .

means in Spock "I expect zero invocations for all other methods of all other classes when the test runs". Also notice that I do not care how many times the isEmpty() method is called and I use the underscore operator in the cardinality.

_ * inventory.isEmpty() >> false

This line means "I expect the isEmpty() method to be called any number of times, and when it does it should return false".

The many faces of the underscore character.

As you may have noticed by now the underscore character is a special matcher for Spock tests. In the basic form of a mock verification N * class.method(argument), the underscore can be used to match arguments (listings 6.16, 6.17), methods (listing 6.18), classes and even the cardinality N (listing 6.19). For all these cases it means that you do not care about the respective part of the verification.

6.3.6 Verifying types of arguments when a mocked method is called

I have shown you how you can verify specific arguments in mock invocations and how you can say to Spock that you do not care about arguments (the underscore character). However, in between these two extremes you can verify several other attributes of arguments. One of the most useful verifications is to make sure that the argument passed is not null. This can be described very naturally in Spock.

Listing 6.20 Verifying that arguments were not null when a mocked method is called

def "Warehouse is queried for each product - null "() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and: "a warehouse with limitless stock" WarehouseInventory inventory = Mock(WarehouseInventory) #A basket.setWarehouseInventory(inventory) when: "user checks out both products" basket.addProduct tv basket.addProduct camera boolean readyToShip = basket.canShipCompletely() then: "order can be shipped" readyToShip 2 * inventory.isProductAvailable(!null ,1) >> true #B}

#A Creation of a Spock mock

#B Verifying that the first argument is not null.

In code listing 6.20 I want to make sure that whatever argument is passed to the inventory is not null (because they should be names of products). For the second argument where I know exactly what will be used I put directly the value.

2 * inventory.isProductAvailable(!null ,1) >> true

This line means "I expect that the method isProductAvailable() will be called twice. The first argument can be anything apart from null, and the second argument will always be 1. When that happens the method will return true".

In unit tests with complex class hierarchies you can verify the type of arguments as well. Code listing 6.21 illustrates this (for this trivial example it is probably an overkill).

Listing 6.21 Verifying the type of arguments

def "Warehouse is queried for each product - type "() { given: "a basket, a TV and a camera" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) Basket basket = new Basket() and: "a warehouse with limitless stock" WarehouseInventory inventory = Mock(WarehouseInventory) #A basket.setWarehouseInventory(inventory) when: "user checks out both products" basket.addProduct tv basket.addProduct camera boolean readyToShip = basket.canShipCompletely() then: "order can be shipped" readyToShip 2 * inventory.isProductAvailable(_ as String ,_ as Integer) >> true #B}

#A Creation of a Spock mock

#B Verifying that the first argument is always a String and the second always an Integer.

Again we use the magic underscore character this time combined with the as keyword. Notice that a null argument will also fail the verification so the as/underscore combination includes the null check.

6.3.7 Verifying arguments of method calls from mocked classes

Using the underscore character as an argument in your mock verifications means that you do not care about the argument at all. But what happens if you unit test is actually focused on the arguments themselves and you docare?

In that case my advice is to declare exactly what you expect. You have seen already that with scalar values, you just use them directly as arguments. The same thing happens with full objects.

Listing 6.22 Verifying exact arguments of a mocked method

def "vip status is correctly passed to credit card - simple"() { given: "a basket, a customer and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false,creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) #A basket.setCreditCardProcessor(creditCardSevice) when: "user checks out two products" basket.addProduct tv basket.addProduct camera basket.checkout(customer) then: "credit card is charged" 1 * creditCardSevice.sale(1550, customer) #B}

#A Creation of a Spock mock

#B Verifying that the second argument is equal to a specific object instance

As you can see in listing 6.22 there is no special syntax for objects:

1 * creditCardSevice.sale(1550, customer)

This line means that "when the test ends I expect the sale() method to be called exactly once. Its first argument should be the number 1500 and its second argument should be the customer instance".

If you want to verify part of an object instance and not the whole instance you can use Groovy closures in a similar way to stubs (as was shown in listing 6.8). The same syntax applies to Mocks as seen below:

Listing 6.23 Verifying part of a object instance used as a mock argument

def "vip status is correctly passed to credit card - vip"() { given: "a basket, a customer and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false,creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) #A basket.setCreditCardProcessor(creditCardSevice) when: "user checks out two products" basket.addProduct tv basket.addProduct camera basket.checkout(customer) then: "credit card is charged" 1 * creditCardSevice.sale(1550, { client -> client.vip == false}) #B}

#A Creation of a Spock mock

#B Verifying that the second has a field called vip with value false

The last verification line in listing 6.23 checks only the vip field of the Customer object. The other two fields (name and creditCard) can be anything and the test will still pass. Of course with the power of Groovy closures you can check a mocked argument against any expression you can think of.

Listing 6.24 Using full Groovy closures for argument verification

def "vip status is correctly passed to credit card - full"() { given: "a basket, a customer and a TV" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false,creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) basket.setCreditCardProcessor(creditCardSevice) when: "user checks out two products" basket.addProduct tv basket.addProduct camera basket.checkout(customer) then: "credit card is charged" 1 * creditCardSevice.sale({amount -> amount == #B basket.findOrderPrice()}, { client -> client.vip == false}) #B}

#A Creation of a Spock mock

#B Custom expression for both mocked arguments

In listing 6.24 I have used two closures, one for each argument of the sale() method. The second closure as before checks a single field of an object (the vip field from the customer class). The first closure makes its own calculation with a completely external method - the findOrderPrice().

1 * creditCardSevice.sale({amount -> amount == basket.findOrderPrice()}, { client -> client.vip == false})

The whole line means "when this unit test is complete I expect the sale method to be called exactly once. It should have two arguments. The first argument should be equal to the result of basket.findOrderPrice(). The second argument should be an object instance with a vip field. The value of the vip field should be false".

If any facts of this sentence do not stand, the Spock test will fail. All of them must be correct for a successful test.

6.4 Putting it all together- Credit card charging in two steps

All the examples shown so far were illustrating various features for Mocks and Stubs. I will close this chapter with a bigger example that combines most of the techniques shown so far and is closer to what you would write in a production application.

If you look back at listing 6.14 you will see that the basket class also contains a method fullCheckout(). This method does the following

1. Checks the credit card of the customer. If the card is invalid or it does not have enough funds it stops there.

2. If the credit card is ok, the price for the products is reserved from the credit card. (This is called an authorization event in credit card terminology)

3. Then the inventory is checked. If the products are in stock and can be shipped, the amount from the card that was previously reserved is now transferred to the account of the eshop (this is called a capturing event in credit card terminology)

In listing 6.12 you can see these two methods (for authorization and capturing) in the credit card processor class. A diagram that shows what we want to test is shown below.

Figure 6.4 - Business requirements for credit card charging

As a starting point, the first scenario that we will test is the case where the card does not have enough money. Here is the Spock test:

Listing 6.25 Using Mocks and Stubs in the same test

def "card has no funds"() { given: "a basket, a customer and some products" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false,creditCard:"testCard") and: "a credit card service" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor) #A basket.setCreditCardProcessor(creditCardSevice) and: "a fully stocked warehouse" WarehouseInventory inventory = Stub(WarehouseInventory) #B { isProductAvailable(_ , _) >> true #B isEmpty() >> false #B } basket.setWarehouseInventory(inventory) when: "user checks out two products" basket.addProduct tv basket.addProduct camera boolean charged = basket.fullCheckout(customer) #C then: "nothing is charged if credit card does not have enough money" 1 * creditCardSevice.authorize(1550, customer) >> #D CreditCardResult.NOT_ENOUGH_FUNDS !charged #E 0 * _ }

#A Creation of a Spock mock

#B Stubbing the inventory to be full

#C Triggering the tested action

#D Mocking the credit card to be invalid

#E Verifying that nothing was charged

The resulting code does not have any surprises. Because we directly mock the credit card processor to assume that card does not have enough money, the charging process stops.

Things get more interesting if we want to write a unit test for the full scenario where the card is OK. The complicated part here is the two step process between the "authorize" and "capture" steps. The reason for this is that the response from the first is a special token (assume that in our example it is a single string). Then when the basket calls the "capture" step it must pass the same token to the credit card processor. This way the credit card processor can link the two events together and distinguish multiple "capture" events.

To further complicate things assume also that the credit card processor wants the current date pre-pended to the token for logistical reasons. The diagram below shows a sample conversation between the basket class and the credit card processor.

Figure 6.5 - Two steps of charging a credit card with the same token

The respective unit tests is shown below:

Listing 6.26 Verifying a sequence of events with interconnected method calls

def "happy path for credit card sale"() { given: "a basket, a customer and some products" Product tv = new Product(name:"bravia",price:1200,weight:18) Product camera = new Product(name:"panasonic",price:350,weight:2) BillableBasket basket = new BillableBasket() Customer customer = new Customer(name:"John",vip:false,creditCard:"testCard") and: "a credit card that has enough funds" CreditCardProcessor creditCardSevice = Mock(CreditCardProcessor)#A basket.setCreditCardProcessor(creditCardSevice) CreditCardResult sampleResult = CreditCardResult.OK sampleResult.setToken("sample"); #B and: "a warehouse" WarehouseInventory inventory = Mock(WarehouseInventory) #C basket.setWarehouseInventory(inventory) when: "user checks out two products" basket.addProduct tv basket.addProduct camera boolean charged = basket.fullCheckout(customer) #D then: "credit card is checked" 1 * creditCardSevice.authorize(1550, customer) >> sampleResult #E then: "inventory is checked" with(inventory) #F { 2 * isProductAvailable(!null , 1) >> true #G _ * isEmpty() >> false } then: "credit card is charged" 1 * creditCardSevice.capture({myToken -> myToken.endsWith("sample")}, customer) >> CreditCardResult.OK #H charged #I 0 * _ #J}

#A Mocking the credit card service

#B Creating a sample credit card token

#C Mocking the warehouse

#D Triggering the tested action

#E Passing the sample token to the basket class

#F Grouping interactions using with()

#G Verifying that the inventory is queried twice (once for each product)

#H Verifying that the previous token is re-used by the basket class

#I Verifying that the credit card was indeed charged

#J Making sure that no other method from mocks was called

There are several key points demonstrated in listing 6.26. First of all, this time around the warehouse inventory is a mock instead of a stub, because I want to verify the correct calling of its methods. I also want to verify that it gets non-null arguments.

Mocks and Stubs support the with() Spock method that was introduced in Chapter 4. I have used it to group the two interactions of the Warehouse inventory.

To verify that the basket class honors the token given back by the credit card processor I create my own dummy token (named sample) and pass it to the basket when the authorization step happens. I can then verify that the token handed to the capture event is the same. Because the basket also prepends the token with the date (which is obviously different each time the test runs) I have to use the endsWith() method in the Groovy closure that matches the token.

Mocks and Stubs are relevant only to the scenario being tested

If you look at listing 6.25 you will see that the Warehouse is a Stub. However on listing 6.26 it is a Mock. It is therefore possible to create Stubs of a specific class in one unit test, and Mocks of the same class in another unit test, depending on your business needs. Also it is possible to have Spock tests that use only Stubs, tests that use only Mocks and tests that use both depending on the case (if you look back at the examples of this chapter). Use whatever you need according to the situation

And there you have it! I have tested two credit card scenarios without actually charging a real credit card and without calling the real credit card service which might be slow to initialize. As an exercise[61] feel free to create more unit tests to cover:

· the case where the card becomes invalid between the authorize and capture steps

· the case where the authorize step succeeds but the inventory does not have the products in stock.

6.5 Architecture considerations for effective mocking/stubbing

I will close this chapter with some theory which is not strictly specific to Spock, but is otherwise essential to effective unit tests that contain mocks and stubs.

6.5.1 Designing testable code that allows painless mocking

If by reading the examples in this chapter you got the feeling that I was always lucky with how easily collaborator classes were mocked and stubbed, you are half-way correct. One of the prerequisites of easy mocking is to have written your source code in a testable manner. By that I mean:

· code that is injected with its dependencies (inversion of control)

· No static classes/global state

· No static fields

· No singletons

· No complex constructors

· No service locators and hidden dependencies

Spock (or any other testing framework for that matter) cannot really help you if the production code is not in a usable state. It really helps if you follow the test-driven-development paradigm when you create Spock tests.

Also note that at least for Java production code, Spock cannot mock static methods and/or private methods[62] on its own. This is done by design[63]. And even though this might seem like a limitation, you should see it as a motivation on writing testable code. For more information you should consult the "Test Driven" book also by Manning (http://www.manning.com/koskela/). The book talks about JUnit, but the advice it gives on testable Java code also applies to Spock.

If you really, really want to mock static/private methods you need to use a framework such as Powermock (https://code.google.com/p/powermock/). You might already have experience with it, because Mockito also does not support mocking of private methods and it needs Powermock for this purpose as well. I personally do not like the Powermock solution (it uses a custom classloader and bytecode manipulation) and would only use it as a last resort solution. Spock can be used together[64] with Powermock via the PowerMockRule JUnit rule (https://code.google.com/p/powermock/wiki/PowerMockRule)

6.5.2 Lenient versus strict mocks

The underscore character is very powerful in Spock, and as you have seen, it can be used on a wide area from single arguments, to full classes. However, as with all things in software engineering there is a trade-off between strict tests (that specify explicitly all interactions and arguments) and lenient tests (that rely heavily on the underscore character and the default stubbing behavior of Spock)

Strict tests will catch more subtle bugs, but in the long run they will be hard to maintain as even the slightest change in external interfaces or business requirements will make them break. Even adding a single method to a class that is used in a mock will instantly break any test that uses the "0 * _" line as a last statement.

On the other hand lenient tests will not break very often but may miss some hard to reproduce bugs which happen because of corner cases and strange combinations of arguments.

My advice to you is to use strict tests for the mission critical parts of your application and lenient test for everything else. Following the Pareto principle (http://en.wikipedia.org/wiki/Pareto_principle) this means that about 20% of your tests should be strict and the rest (80%) should be lenient. As always of course this is just a suggestion that should be only a starting point for your own application and your own business needs.

6.6 Summary

· Fake classes can be used in unit tests instead of real classes. They are needed in several cases, such as when the real implementations are slow or have severe side effects.

· Spock supports two kinds of fakes classes: Mocks and Stubs. Stabs are fake classes with preprogrammed behavior. Mocks are fake classes with preprogrammed behavior that can also be queried at the end of the test for their interactions.

· Spock can mock/stub both Java interfaces and concrete Java classes.

· Canned responses in Stubs are programmed with the right-shift operator - >>

· Preprogrammed responses can be differentiated according to the argument method or the number of times a method was called.

· The unsigned-right-shift operator - >>> - can be used to stub sequential calls of the same method with the same arguments.

· The underscore character acts as a universal matcher in Spock, when you don't care about the exact content of a call. It can be used to match arguments, methods, classes or even number of times a method was called.

· By using Groovy closures, a stub can be instructed to throw exceptions, run custom statements or perform any other side effects.

· Groovy closures can also be used in stubs to create dynamic responses according to the argument passed to the stubbed method.

· It is possible to mix, the underscore operator, fixed arguments and Groovy closures in the same stubbed method call.

· Stubs/Mocks can return other Stubs/Mocks. Recursive stub creation is possible if legacy production code requires it.

· In Spock, Mocks are a superset of Stubs, but for readability reasons you should only use Mocks when you want to verify the interaction with the class under test. For fake objects that are only used for their responses you should use Stubs.

· By default, the order of mock verifications inside a then: block does not matter. You should use multiple then: blocks if you care about the order of verifications. Each then: block will be evaluated in turn.

· It is possible to verify the number of times a method was called. Using zero as cardinality means that you expect that a method was never called. Using the underscore character means that you don't care how many times it was called.

· You can verify arguments of a mocked method to ensure that they were not null, or that they had a specific type.

· You can use Groovy closures as argument catchers to perform further validations on specific arguments of mocked methods.

· As with JUnit/Mockito, Spock is more easily applied to Java code that is designed to be testable in the first place.

· With Java classes, Spock cannot mock private methods and static methods/objects. You should refactor your Java code first before writing Spock tests or use Powermock if you are really desperate.

· Care must be exercised with the underscore character. It can result in lenient tests that let subtle bugs slip through.

[53] A good start would be the book "Effective Unit tests" also by Manning - Chapter 3 in particular.

[54] and which should be Spies in some cases. Spies will be shown in chapter 8.

[55] Unlike Mockito, Spock supports partial matching of arguments where some have specific values and some have not. Mockito requires that all arguments use matchers if any matcher is used at all.

[56] Not really sustainable for a true shop, but it will be enough for illustration purposes.

[57] Otherwise the world will explode.

[58] This was shown in chapter 4

[59] and have been paying close attention to the code listings

[60] This is a big difference with Mockito. In Mockito you can separately stub a mock and verify it in another statement. In Spock you do both things at the same time.

[61] A possible solution can be found on the source code of the book in Github

[62] On a related note for a really detailed guide on testing private methods see http://www.shoulditestprivatemethods.com

[63] Mockito also does not support mocking of static/private methods.

[64] See https://github.com/kriegaex/Spock_PowerMock for an example.