Как заглушить репозиторий Spring, чтобы создать исключение в интеграционном тесте? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть служба, у которой есть хранилище в качестве параметра конструктора.

@Autowired
NodeServiceListInstallService( final BykiListRepository aBykiListRepository )

BykiListRepository - это хранилище Spring по умолчанию без реализации

interface BykiListRepository extends JpaRepository<BykiList, Long> {
    //some magic methods
}

Мой класс конфигурации помечен @EnableJpaRepositories, поэтому у меня нет прямого объявления бина. Сервисная декларация:

@SpringBootApplication
@EnableConfigurationProperties( ApplicationProperties )
@EnableJpaRepositories
@EnableTransactionManagement
@ImportResource( 'classpath:META-INF/spring/application-context.xml' )
class Application extends SpringBootServletInitializer {
    @Bean
    NodeServiceListInstallService nodeServiceListInstallService( final BykiListRepository bykiListRepository ) {
        new NodeServiceListInstallService( bykiListRepository )
    }
}

Я пытаюсь написать тест в рамках вызова метода репозитория save сгенерирует исключение PersistenceException. Я пытался заглушить / шпионить хранилище и объявить его как bean-компонент в @TestConfiguration с @Primary, или даже реализовать интерфейс. Но у меня нет результата.

@TestConfiguration
class TestConfig {
    @Bean
    BykiListRepository bykiListRepository() {
        //return Spock's Spy/Stub or new BykiRepositoryBadImpl()
    }

Тест:

@ContextConfiguration( classes = TestConfig )
class GlobalErrorHandlerIntegrationTest extends BaseFlowIntegrationTest {
    //test()
}

Я пишу на Groovy-2.4.12 и пишу тесты с Spock-1.1. Spring Boot 1.5.4. Зарезервированный вариант заключается в использовании аспекта, но не совсем то, что я хочу. Буду очень признателен за помощь.

Обновление: использование DetachedMockFactory:

Конфигурация:

@ TestConfiguration

class DummyConfiguration {
    private final detachedFactory = new DetachedMockFactory()
    @Bean
    @Primary
    BykiListRepository bykiListRepository() {
        detachedFactory.Mock( BykiListRepository )
    }
}

Скелет теста:

@SpringBootTest( classes = DummyConfiguration )
@Import( [DummyConfiguration] )
@ContextConfiguration( classes = DummyConfiguration )
class GlobalErrorHandlerIntegrationTest extends BaseFlowIntegrationTest {
    @Autowired
    BykiListRepository bykiListRepositoryMock
    def 'exercise error handling'() {
        given: 'the failing repository'
        bykiListRepositoryMock.save( _ ) >> {
            throw new CannotCreateTransactionException()
        }
        when: 'the message is send to rabbit'
        rabbitOperations.send( configuration.rabbitExchangeName, '', msg )
    }
}

где:

@SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.NONE )
@ContextConfiguration( classes = Application )
class BaseFlowIntegrationTest extends AbstractIntegrationTest {...}

И

@Category( InboundIntegrationTest )
abstract class AbstractIntegrationTest extends Specification {...}

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Проблема была в том, что у меня было неверное имя.Я изменил его на bykiListRepositoryMock (вместо bykiListRepository), и это решило проблему.

0 голосов
/ 06 сентября 2018

Вы можете создать test configuration, как показано ниже, и используя запись Спока при вызове какой-либо функции, тогда будет выброшен ex. Конечно, используйте @Inject or @Autowire в тестовом классе ... и сделайте @Import([IntegrationTestMockingConfig])

@TestConfiguration
class IntegrationTestMockingConfig {

     private DetachedMockFactory factory = new DetachedMockFactory()

     @Bean
     ExternalRepository externalRepository() {
         factory.Mock(ExternalRepository)
     }
}
...