This is the 15th day of my participation in the August Text Challenge.More challenges in August

The last article briefly introduced the concept of Spock. This article begins to learn the application of Spock step by step from a practical point of view. Since the entire test code needs to be written in Groovy, you can easily learn some of the language if necessary. If you don’t want to learn, use the official demo can also fully cover the basic needs.

Spock has some important concepts:

Specification

This is spock’s base class, which contains a number of more important methods. Every single test class inherits from this class.

Fields

Many fields are defined here, which is part of the Setup phase, where the Spring bean that needs to mock or the return after the mock is defined. Here’s an example:

def studentDao = Mock(StudentDao)
def tester = new StudentService(studentDao: studentDao)
...
given: "Set request Parameters"
def student1 = new StudentDTO(id: 1.name: "Zhang".province: "Beijing")
def student2 = new StudentDTO(id: 2.name: "Bill".province: "Shanghai")

Copy the code

Fixture Methods

Fixed method. Here are some of the presets in Specification:

def setupSpec() {} // runs once - before the first feature method def setup() {} // runs before every feature method def  cleanup() {} // runs after every feature method def cleanupSpec() {} // runs once - after the last feature methodCopy the code

This can be interpreted as the warm-up of the data, and the completion of the cleanup. This has a similar concept in junit as a prerequisite for unit testing.

Feature Methods

This is where Spock excels. It provides a set of testing procedures that even non-technical people can understand at a glance, and is extremely easy to write. It is divided into the following types:

Dynamic method name

When executing a single test, each push element is printed as follows, especially for if/else branches

def "pushing an element #element on the stack"() {
  // blocks go here
}
Copy the code

Given Blocks

As the name suggests, here is the input, with some instructions:

given: "setup new stack and input elemet"
def stack = new Stack()
def elem = "push me"
Copy the code

Given is optional and can be used instead with the setup() method.

When and Then Blocks

It’s also very easy to understand what the outcome should be when something happens. This is similar to Assert in junit. Here’s an example:

when: "push stack" stack.push(elem) then: "check stack status" ! stack.empty stack.size() == 1 stack.peek() == elemCopy the code

The operations here are very extensive and cover is very broad, but they are basically Boolean operations that also include exception judgments. We can talk about it later.

Expect Blocks

This is similar to when/then, and is more suitable for relatively simple tests, such as one-line expressions:

when:
def x = Math.max(1, 2)

then:
x == 2
Copy the code
expect:
Math.max(1, 2) == 2
Copy the code

It saves code and makes it cleaner.

Cleanup Blocks

As a scavenger, some resources need to be released, otherwise other test cases may be affected.

given:
def file = new File("/some/path")
file.createNewFile()

// ...

cleanup:
file.delete()
Copy the code

Of course you can choose to use the cleanup() method, but using the cleanup block is more flexible.

Where Blocks

Where is always the last block and cannot be repeated, which is even more useful in Data Driven Testing. Here’s a quick example:

def "computing the maximum of two numbers"() {
  expect:
  Math.max(a, b) == c

  where:
  a << [5, 3]
  b << [1, 9]
  c << [5, 9]
}
Copy the code

A calculation formula is declared in Expect, and a variety of calculations and expectations can be made against this formula in WHERE. The implication here is that if a=5 and b=1 then c=5; When a is equal to 3 and b is equal to 9, c is equal to 9, and we calculated the maximum value by the way we maximized it.