Reading a test dataset from an external source

Một phần của tài liệu Manning java testing with spock (Trang 76 - 79)

One of the challenges I face when creating a new unit test (especially in test-driven development, as the test is created before the implementation code) is finding correct test input. For basic unit tests in which only a single class is tested, you might get away with trivial data created on the spot.

For integration tests, however, which test multiple code modules, your selection of test data needs more thought. Once you have enough tests for the happy paths of your code, it’s time to examine all corner cases and strange scenarios. Creating effective test data is a separate skill of its own, but a good source of such data can be found on an existing running system. Often, test data can also be obtained from issues reported by the users of the software. These types of data are as real as they get, so they’re excel- lent candidates for your unit tests.

Unfortunately, useful test data is often trapped in the transport medium (for example, XML files) that must be processed before they can be used directly in a unit test. Groovy comes with excellent facilities for extracting test data from external files, and you should take advantage of these techniques in your Spock tests. Using the Java approach will also work, but again in a much more verbose way.

2.4.1 Reading a text file

Reading a text file in Java usually requires a basic understanding of buffered readers or any other Java file API that was added with each new Java version.11 Groovy does away with all the unneeded craft and allows you to read a file in the simplest way possible:

String testInput = new File("src/test/resources/quotes.txt").text Listing 2.20 Using Groovy multiline strings

11 Or coming from an external library such as Apache Commons.

Creation of a multiline string

Using the multiline string

A normal file is opened. Groovy adds the .getText() method that reads its text. You could also specify the encoding if it’s not the default. This simplicity is handy because it can be used straight in a Spock test. The following listing shows an example.

def "demo for reading a text file"() { when: "a paragraph is processed"

WordDetector wordDetector = new WordDetector();

String inputText = new File("src/test/resources/quotes.txt").text wordDetector.parseText(inputText);

then: "word frequency should be correct"

wordDetector.wordsFound() == 78 }

def "demo for reading a text file line by line"() { when: "a paragraph is processed"

List<String> inputText = new

File("src/test/resources/quotes.txt").readLines() WordDetector wordDetector = new WordDetector();

for(String line:inputText) {

wordDetector.feedText(line) }

then: "word count should be correct"

wordDetector.wordsFound() == 78 }

Notice the expressive code. It has no boilerplate for autoclosing streams or anything like that. I’ll show you more examples of file reading in chapter 5, where Groovy code is both shorter and easier to understand than the Java way. In chapter 5, I’ll show you data-driven Spock tests in which the same test is evaluated for multiple (similar) sets of input test data.

2.4.2 Reading an XML file

XML is the lingua franca of large enterprise applications. One of the original market- ing points of Java was the handling of XML files. Business web services usually produce some sort of XML dialect, and several custom file formats are XML files under the hood. As with Java, Groovy supports several ways, but explaining them all is outside the scope of this chapter.

This section demonstrates the XmlSlurper way of reading XML files with Groovy.

You can use this technique either when you want to read test data from an XML file, or when your Java class writes XML and you want to quickly verify its correctness.12

Listing 2.21 Reading test data from a file in a Spock test

12 For more-complex XML verification cases, you can also use a dedicated XML diff library such as XMLUnit.

Reading the whole text file

Reading a file line by line

53 Reading a test dataset from an external source

Let’s assume that your XML file is the following:

<staff>

<department name="sales">

<employee>

<firstName>Orlando</firstName>

<lastName>Boren</lastName>

<age>24</age>

</employee>

<employee>

<firstName>Diana</firstName>

<lastName>Colgan</lastName>

<age>28</age>

</employee>

</department>

</staff>

The next listing provides the respective Groovy code.

def xmlRoot = new

XmlSlurper().parse('src/main/resources/employee-data.xml') assert xmlRoot.department.size() ==1 assert xmlRoot.department.@name =="sales"

assert xmlRoot.department.employee.size() ==2 assert xmlRoot.department.employee[0].firstName =="Orlando"

assert xmlRoot.department.employee[0].lastName =="Boren"

assert xmlRoot.department.employee[0].age ==24

assert xmlRoot.department.employee[1].firstName =="Diana"

assert xmlRoot.department.employee[1].lastName =="Colgan"

assert xmlRoot.department.employee[1].age ==28

Here you can see the expressive Groovy power in all its glory. Reading the XML file is a single line. Then you use an XPath-like expression to retrieve XML content. I won’t even bother to write the Java code for the same example. XML reading (and writing) in Java has always contained boilerplate code, which is taken for granted by Java devel- opers. Groovy discards all this and keeps only the substance.

2.4.3 Reading a JSON file

Groovy reads JavaScript Object Notation (JSON) in a similar way to how it reads XML. XML might be dominant in legacy enterprise applications, but newer web services tend to use JSON. Groovy covers them both with ease.

Let’s assume that your JSON file is the following:

{

"staff": {

"department": { "name": "sales", "employee": [

Listing 2.22 Reading XML in Groovy

Creating the XmlSlurper object Checking the number of children XML nodes Accessing

an XML

property Accessing XML content

of the first child Accessing XML content of the second child

{

"firstName": "Orlando", "lastName": "Boren", "age": "24"

}, {

"firstName": "Diana", "lastName": "Colgan", "age": "28"

} ] } } }

The next listing presents the respective Groovy code (almost the same as the XML one).

def jsonRoot = new JsonSlurper().parse(new

File('src/main/resources/employee-data.json'))

assert jsonRoot.staff.department.name =="sales"

assert jsonRoot.staff.department.employee.size() ==2 assert jsonRoot.staff.department.employee[0].firstName =="Orlando"

assert jsonRoot.staff.department.employee[0].lastName =="Boren"

assert jsonRoot.staff.department.employee[0].age =="24"

assert jsonRoot.staff.department.employee[1].firstName =="Diana"

assert jsonRoot.staff.department.employee[1].lastName =="Colgan"

assert jsonRoot.staff.department.employee[1].age =="28"

With Groovy, obtaining test data from JSON is easy. The syntax is even simpler than XML in some ways.

Một phần của tài liệu Manning java testing with spock (Trang 76 - 79)

Tải bản đầy đủ (PDF)

(306 trang)