Как упоминалось в предыдущем посте , 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 представляет собой фиктивный список, а не получаемый из база данных.
Более подробную информацию о способах насмешки Спока можно найти на домашней странице проекта .