2017-08-10 89 views
0

我目前使用spring-boot实现了一些存储库方法,如@Async,它的工作方式应该是在我实际启动应用程序时,但在运行集成测试时,开始行动怪异。@DataJpaTest和@Async CRUDRepository方法不一起工作

我已经设置了一个展示问题的小项目。

库:

interface MyObjectRepository : CrudRepository<MyObject, Long> { 

    @Async 
    fun findBySomething(something: String): ListenableFuture<MyObject?> 

} 

应用:

@SpringBootApplication 
@EnableAsync 
class Application { 

    private val log = LoggerFactory.getLogger(Application::class.java) 

} 

fun main(args: Array<String>) { 
    SpringApplication.run(Application::class.java, *args) 
} 

我的测试用例:

@RunWith(SpringRunner::class) 
@DataJpaTest 
class MyObjectRepositoryTest { 

    @Autowired 
    lateinit var target: MyObjectRepository 

    @Before 
    fun `init`() { 
     target.deleteAll() 
    } 

    @Test 
    fun `should be able to find MyObject`() { 
     val m = MyObject("something") 
     val expected = target.save(m) 

     val futureResult = target.findBySomething("something") 
     val result = futureResult.get() 

     assert.that(result, equalTo(expected)) 
    } 
} 

我的结果:

expected == the object (good)

result == null (bad)

如果我对库类级别启用@Async,结果被周围的翻转。

如果我进一步使测试睡眠调用target.save(m)expectedresultnull

任何人有任何建议,这可能是错后?我是否错过了某些东西(如用于测试目的的注释?)。

再说一次,当我启动应用程序,并对我的控制器进行其他调用时,一切正常。

回答

0

我建议不要使用@DataJpaTest,因为您想要使用Spring测试另一个组件以及JPA存储库。

Spring Boot Slice测试,像@WebMvcTest,@JsonTest等只加载一个应用程序上下文的切片,而不是整个事情。它们只加载特定的自动配置,以及某些测试依赖关系。我猜想在使用时会丢失@DataJpaTest

我会建议使用@SpringBootTest,虽然这也可能是相当重的,因为它加载,绝大多数应用程序。

+0

这使得结果成为一些东西。尽管现在assert仍然失败(我还没有实现自定义的equals方法,但这不是'@ DataJpaTest'注释的问题,运行时没有'@ Async')。用一个简单的'println()'我可以告诉对象具有相同的属性。我将继续用'@ SpringBootTest'来代替它,因为它更接近永久解决方案atm。 –

+0

更新:平等失败与hibernate的PersistentBag有关,因为我的生产代码有一个对象列表作为一个字段。当使用'@DataJpaTest'时,类型是'ArrayList','@SpringBootTest'是'PersistentBag'。 (无法编辑我的其他答案) –