如何存根 Spring 存储库以在集成测试中抛出异常?
How to stub Spring repository to throw an exception in an integration test?
我有一个服务,它有一个存储库作为构造函数的参数。
@Autowired
NodeServiceListInstallService( final BykiListRepository aBykiListRepository )
BykiListRepository
是默认的 Spring 存储库,没有实现
interface BykiListRepository extends JpaRepository<BykiList, Long> {
//some magic methods
}
我的配置class标记为@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
。
我已经尝试 stub/spy 一个存储库并在 @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 {...}
您可以像下面那样创建 test configuration
并在调用某些函数时使用 Spock 记录,然后将抛出 ex。当然,在测试 class 中使用 @Inject or @Autowire
... 并执行 @Import([IntegrationTestMockingConfig])
@TestConfiguration
class IntegrationTestMockingConfig {
private DetachedMockFactory factory = new DetachedMockFactory()
@Bean
ExternalRepository externalRepository() {
factory.Mock(ExternalRepository)
}
}
问题是因为我的bean 名称错误。我已将其更改为 bykiListRepositoryMock
(而不是 bykiListRepository
)并解决了问题。
如果您想使用模拟存储库抛出异常 -
when(repository.yourMethodName(anyString(), anyString(), anyString())).thenThrow(new PersistenceException("Persistence exception occurred"));
如果你想抛出任何特定的持久性异常,那么你也可以抛出。
https://www.objectdb.com/api/java/jpa/exceptions
我有一个服务,它有一个存储库作为构造函数的参数。
@Autowired
NodeServiceListInstallService( final BykiListRepository aBykiListRepository )
BykiListRepository
是默认的 Spring 存储库,没有实现
interface BykiListRepository extends JpaRepository<BykiList, Long> {
//some magic methods
}
我的配置class标记为@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
。
我已经尝试 stub/spy 一个存储库并在 @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 {...}
您可以像下面那样创建 test configuration
并在调用某些函数时使用 Spock 记录,然后将抛出 ex。当然,在测试 class 中使用 @Inject or @Autowire
... 并执行 @Import([IntegrationTestMockingConfig])
@TestConfiguration
class IntegrationTestMockingConfig {
private DetachedMockFactory factory = new DetachedMockFactory()
@Bean
ExternalRepository externalRepository() {
factory.Mock(ExternalRepository)
}
}
问题是因为我的bean 名称错误。我已将其更改为 bykiListRepositoryMock
(而不是 bykiListRepository
)并解决了问题。
如果您想使用模拟存储库抛出异常 -
when(repository.yourMethodName(anyString(), anyString(), anyString())).thenThrow(new PersistenceException("Persistence exception occurred"));
如果你想抛出任何特定的持久性异常,那么你也可以抛出。 https://www.objectdb.com/api/java/jpa/exceptions