【问题标题】:How can I use @SpringBootTest(webEnvironment) with @DataJpaTest?如何将@SpringBootTest(webEnvironment) 与@DataJpaTest 一起使用?
【发布时间】:2024-04-24 03:45:02
【问题描述】:

我正在尝试测试 JAX-RS 应用程序,但我不想模拟数据,尤其是因为现有的 @DataJpaTest 有一个 buildData 方法

这是我目前正在尝试的:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    classes = MyApp.class
)
@DirtiesContext
@DataJpaTest
public class MyResourceTest {

我收到以下错误

java.lang.IllegalStateException:配置错误:发现测试类 [app.MyResourceTest] 的多个 @BootstrapWith 声明:[@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test. context.SpringBootTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper)]

我看到的其他类似的不要谈论webEnvironment设置:

使用@AutoConfigureTestDatabase 有一些解决方案,但是当我这样做时,只有第一个有效,因为buildData@Before 注释(与@DataJpaTest 相同),因为我希望数据之前是原始的每个测试,所以我可以做失败的场景。

切换到@BeforeClass 也不起作用,因为我将无法使用@Autowire Repository 对象。

【问题讨论】:

    标签: java spring jpa testing jax-rs


    【解决方案1】:

    @DataJpaTest 文档声明如下:

    如果您希望加载完整的应用程序配置,但使用嵌入式数据库,则应考虑将@SpringBootTest@AutoConfigureTestDatabase 结合使用,而不是此注释。


    请记住,@DataJpaTest 带有 @Transactional@DirtiesContext 注释。所以你可能需要这些注释以及@AutoConfigureTestDatabase

    【讨论】:

    • 刚刚更新我的 OP,因为我已经按照你的建议做了。
    • @ArchimedesTrajano 我刚刚看到你的更新。我认为@Transactional@DirtiesContext 应该可以解决问题。
    • 更新你的答案,说@Transactional@DirtiesContext,这样我就可以接受了。
    • 其实我发现了一个问题,当我使用restTemplate获取数据时,数据库中似乎没有任何内容,但这可能是因为我没有正确地构建数据。
    【解决方案2】:

    实际上,在https://*.com/a/57609911/242042 中回答时,它解决了当前的问题,但是您将无法使用 REST 客户端进行任何涉及数据库的测试,因为@Transactional 将阻止数据保存要获取的客户端。

    要使其正常工作,不应使用@Transactional。相反,应该使用DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD。这大大减慢了每次测试(例如每次测试 1 秒到 10 秒),但至少它有效。

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        classes = MyApp.class
    )
    @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
    @AutoConfigureTestDatabase
    @AutoConfigureWebTestClient
    public class MyResourceTest {
    
        @Autowired
        private TestRestTemplate restTemplate;
    
        ...
    
    }
    

    【讨论】: