【问题标题】:How to stub Spring repository to throw an exception in an integration test?如何存根 Spring 存储库以在集成测试中引发异常?
【发布时间】:2019-02-11 17:36:43
【问题描述】:

我有一个服务,它有一个存储库作为构造函数的参数。

@Autowired
NodeServiceListInstallService( final BykiListRepository aBykiListRepository )

BykiListRepository 是默认的 Spring 存储库,没有实现

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

我的配置类标有@EnableJpaRepositories,所以,我没有直接bean的声明。服务声明:

@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。 我试图存根/监视一个存储库并将其声明为@TestConfiguration@Primary 中的bean,甚至实现接口。 但我还没有得到结果。

@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 {...}

【问题讨论】:

  • @AnarSultanov 是的,我不明白它对我的情况有何帮助。你能给出一些解释或例子吗??
  • 请提供测试示例,特别是你如何创建和初始化SpringContext
  • 您可以使用 Mockito 或任何模拟框架
  • @Yogi 我使用 Spock。它允许模拟。问题是如何替换注入的存储库 bean。

标签: java spring spring-boot spock spring-test


【解决方案1】:

您可以像下面这样创建test configuration,并在调用某些函数时使用Spock记录,然后将抛出ex。当然,在测试类中使用@Inject or @Autowire...并使用@Import([IntegrationTestMockingConfig])

@TestConfiguration
class IntegrationTestMockingConfig {

     private DetachedMockFactory factory = new DetachedMockFactory()

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

【讨论】:

  • 没有错误。只是注入了真正的豆子。测试 bean 中的断点创建(factory.Mock(ExternalRepository) - 这一行)不执行。
【解决方案2】:

问题是因为我的 bean 名称错误。我已将其更改为bykiListRepositoryMock(而不是bykiListRepository),它已经解决了问题。

【讨论】:

    【解决方案3】:

    如果您想使用模拟存储库引发异常 -

    when(repository.yourMethodName(anyString(), anyString(), anyString())).thenThrow(new PersistenceException("Persistence exception occurred"));

    如果你想抛出任何特定的持久性异常,那么你也可以抛出。 https://www.objectdb.com/api/java/jpa/exceptions

    【讨论】:

      猜你喜欢
      • 2018-02-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2014-06-19
      • 2018-11-24
      • 1970-01-01
      • 2021-07-28
      • 2019-07-19
      相关资源
      最近更新 更多