Как упоминалось в предыдущем посте , Spock — это мощный DSL, построенный на Groovy, который идеально подходит для тестирования TDD и BDD, и в этом посте будет описано, как легко использовать Spock для тестирования классов Spring, в данном случае класс CustomerService из публикации Использование Spring Data для получить доступ к MongoDB . Это также покроет использование Спока для насмешки.
Спок в значительной степени зависит от среды SpringCon TestContext и делает это с помощью аннотации @ContextConfiguration . Это позволяет классу спецификации теста загружать контекст приложения из одного или нескольких местоположений.
Это позволит тестовой спецификации получить доступ к bean-компонентам через аннотацию @Autowired или @Resource . Тест ниже показывает, как вводитсяЭкземпляр CusotmerService можно протестировать с помощью Spock и Spring TestContext: (Это немного надуманный пример для правильного модульного тестирования класса CustomerService, так как вы создадите класс CustomerService в тесте, а не класс, созданный и введенный Spring.)
package com.city81.mongodb.springdata.dao
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import spock.lang.*
import com.city81.mongodb.springdata.entity.Account
import com.city81.mongodb.springdata.entity.Address
import com.city81.mongodb.springdata.entity.Customer
@ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
class CustomerServiceTest extends Specification {
@Autowired
CustomerService customerService
def setup() {
customerService.dropCustomerCollection()
}
def "insert customer"() {
setup:
// setup test class args
Address address = new Address()
address.setNumber("81")
address.setStreet("Mongo Street")
address.setTown("City")
address.setPostcode("CT81 1DB")
Account account = new Account()
account.setAccountName("Personal Account")
List<Account> accounts = new ArrayList<Account>()
accounts.add(account)
Customer customer = new Customer()
customer.setAddress(address)
customer.setName("Mr Bank Customer")
customer.setAccounts(accounts)
when:
customerService.insertCustomer(customer)
then:
def customers = customerService.findAllCustomers()
customers.size == 1
customers.get(0).name == "Mr Bank Customer"
customers.get(0).address.street == "Mongo Street"
}
}
Однако проблема с вышеприведенным тестом заключается в том, что MongoDB должен быть запущен и запущен, поэтому для удаления этой зависимости мы можем смоделировать взаимодействие с базой данных. Платформенный фреймворк Спока предоставляет множество функций, которые вы найдете в подобных фреймворках, таких как Mockito.
Усиливается CustomerServiceTest высмеивает CustomerRepository и устанавливает издевались объекта на CustomerService .
package com.city81.mongodb.springdata.dao
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import spock.lang.*
import com.city81.mongodb.springdata.entity.Account
import com.city81.mongodb.springdata.entity.Address
import com.city81.mongodb.springdata.entity.Customer
@ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
class CustomerServiceTest extends Specification {
@Autowired
CustomerService customerService
CustomerRepository customerRepository = Mock()
def setup() {
customerService.customerRepository = customerRepository
customerService.dropCustomerCollection()
}
def "insert customer"() {
setup:
// setup test class args
Address address = new Address()
address.setNumber("81")
address.setStreet("Mongo Street")
address.setTown("City")
address.setPostcode("CT81 1DB")
Account account = new Account()
account.setAccountName("Personal Account")
List<Account> accounts = new ArrayList<Account>()
accounts.add(account)
Customer customer = new Customer()
customer.setAddress(address)
customer.setName("Mr Bank Customer")
customer.setAccounts(accounts)
when:
customerService.insertCustomer(customer)
then:
1 * customerRepository.save(customer)
}
def "find all customers"() {
setup:
// setup test class args
Address address = new Address()
address.setStreet("Mongo Street")
Customer customer = new Customer()
customer.setAddress(address)
customer.setName("Mr Bank Customer")
// setup mocking
def mockCustomers = []
mockCustomers << customer
customerRepository.findAll() >> mockCustomers
when:
def customers = customerService.findAllCustomers()
then:
customers.size() == 1
customers.get(0).name == "Mr Bank Customer"
}
}
CustomerRepository это путь имени и типа , хотя он может быть выведен только с именем , например ,
def customerRepository = Mock(CustomerRepository)
Внедренный репозиторий customerRepository перезаписывается макетом экземпляра, а затем в тестовой настройке функциональность может быть смоделирована.
В блоке then функции вставки клиентов проверяется количество взаимодействий с методом сохранения customerRepository, а в функции поиска всех клиентов список возвращаемых клиентов из вызова findAll представляет собой фиктивный список, а не получаемый из база данных.
Более подробную информацию о способах насмешки Спока можно найти на домашней странице проекта .