How to do it...

  1. In order to add the Spock tests to our application, we will need to make a few changes to our build.gradle file first. As Spock tests are written in Groovy, the first thing to do is add a groovy plugin to our build.gradle file, as follows:
apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'groovy' 
apply plugin: 'spring-boot' 
  1. We will also need to add the necessary Spock framework dependencies to the build.gradle dependencies block:
dependencies { 
  ... 
  testCompile('org.spockframework:spock-core:1.1-groovy-2.4-rc-2') 
  testCompile('org.spockframework:spock-spring:1.1-groovy-2.4-rc-2') 
  ... 
} 
  1. As the tests will be in Groovy, we will need to create a new source directory for the files. Let's create the src/test/groovy/com/example/bookpub directory in the root of our project.
  2. Now we are ready to write our first test. Create a SpockBookRepositorySpecification.groovy file in the src/test/groovy/com/example/bookpub directory at the root of our project with the following content:

package com.example.bookpub;

import com.example.bookpub.entity.Author;
import com.example.bookpub.entity.Book
import com.example.bookpub.entity.Publisher
import com.example.bookpub.repository.BookRepository
import com.example.bookpub.repository.PublisherRepository
import org.mockito.Mockito
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator
import org.springframework.test.web.servlet.MockMvc
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.context.ConfigurableWebApplicationContext
import spock.lang.Specification

import javax.sql.DataSource

import static org.hamcrest.CoreMatchers.containsString
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest @AutoConfigureMockMvc class SpockBookRepositorySpecification extends Specification { @Autowired private ConfigurableWebApplicationContext context @Autowired private DataSource ds; @Autowired private BookRepository repository; @Autowired private MockMvc mockMvc; void setup() { ResourceDatabasePopulator populator =
new ResourceDatabasePopulator(
context.getResource("classpath:/packt-books.sql")); DatabasePopulatorUtils.execute(populator, ds); } @Transactional def "Test RESTful GET"() { when: def result = mockMvc.perform(get("/books/${isbn}")); then: result.andExpect(status().isOk()) result.andExpect( content().string(containsString(title)) ); where: isbn | title "978-1-78398-478-7"|"Orchestrating Docker" "978-1-78528-415-1"|"Spring Boot Recipes" } @Transactional def "Insert another book"() { setup: def existingBook = repository.findBookByIsbn("978-1-78528-415-1") def newBook = new Book("978-1-12345-678-9",
"Some Future Book", existingBook.getAuthor(),
existingBook.getPublisher() ) expect: repository.count() == 3 when: def savedBook = repository.save(newBook) then: repository.count() == 4 savedBook.id > -1 } }
  1. Execute the tests by running ./gradlew clean test and the tests should get passed.
  1. As Spock integrates with JUnit, we can see the execution report of the Spock tests together with the rest of our test suite. If we open build/reports/tests/index.html in the browser and click the Classes button, we will see our specification in the table, as shown in the following screenshot:
  1. Selecting the com.example.bookpub.SpockBookRespositorySpecification link will take us to the detailed report page, which is as follows:
  1. Next, we will take our tests a bit further and explore the mocking functionality of the database repositories. Let's use PublisherRepository as our candidate to mock, and wire it into the BookController class to provide a getBooksByPublisher functionality. Let's add the following content to the BookController class in the src/main/java/com/example/bookpub/controllers directory at the root of our project:
@Autowired 
private PublisherRepository publisherRepository; 
 
@RequestMapping(value = "/publisher/{id}", method = RequestMethod.GET) 
public List<Book> getBooksByPublisher(@PathVariable("id") Long id) { 
    Optional<Publisher> publisher =
publisherRepository.findById(id);
Assert.notNull(publisher);
Assert.isTrue(publisher.isPresent());
return publisher.get().getBooks(); }
  1. Let's add the following to the Publisher class in the src/main/java/com/example/bookpub/entity directory at the root of our project:
@OneToMany(mappedBy = "publisher") 
@JsonBackReference 
private List<Book> books; 
 
  1. Lastly, let's add a getter and setter for the books to the Publisher entity class as well:
public List<Book> getBooks() { 
    return books; 
} 
 
public void setBooks(List<Book> books) { 
    this.books = books; 
} 
  1. With all the code additions completed, we are ready to add another test to the SpockBookRepositorySpecification.groovy file in the src/test/groovy/com/example/bookpub directory at the root of our project with the following content:
... 
class SpockBookRepositorySpecification extends Specification { 
    ... 
    @MockBean 
    private PublisherRepository publisherRepository 
 
    @Transactional 
    def "Test RESTful GET books by publisher"() { 
        setup: 
          Publisher publisher =  
                    new Publisher("Strange Books") 
          publisher.setId(999) 
          Book book = new Book("978-1-98765-432-1", 
                "Mystery Book", 
                new Author("John", "Doe"), 
                publisher) 
          publisher.setBooks([book]) 
          Mockito.when(publisherRepository.count()). 
                thenReturn(1L)                    
          Mockito.when(publisherRepository.findById(1L)). 
                thenReturn(Optional.of(publisher)) 
 
        when: 
          def result =  
            mockMvc.perform(get("/books/publisher/1")) 
 
        then: 
          result.andExpect(status().isOk()) 
          result.andExpect(content(). 
                string(containsString("Strange Books"))) 
 
        cleanup: 
          Mockito.reset(publisherRepository) 
    } 
} 
  1. Execute the tests by running ./gradlew clean test and the tests should continue to get passed.
..................Content has been hidden....................

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