2

I am trying to test a JAX-RS application but I'd rather not mock the data especially since there's a buildData method for an existing @DataJpaTest

Here's what I am trying so far:

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

I get the following error

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [app.MyResourceTest]: [@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)]

The other ones I saw that are similar do not talk about the webEnvironment setting:

There is somewhat of a solution using @AutoConfigureTestDatabase but when I did that only the first one works because buildData is annotated with @Before (same as in @DataJpaTest) as I want the data to be pristine before each test so I can do failure scenarios.

Switching to @BeforeClass also won't work because I won't be able to use the @Autowire Repository objects.

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265

2 Answers2

3

The @DataJpaTest documentation states the following:

If you are looking to load your full application configuration, but use an embedded database, you should consider @SpringBootTest combined with @AutoConfigureTestDatabase rather than this annotation.


Keep in mind that @DataJpaTest is annotated with @Transactional and @DirtiesContext. So you may need those annotations along with @AutoConfigureTestDatabase.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
1

Actually when doing the answer in https://stackoverflow.com/a/57609911/242042, it solves the immediate problem, but you won't be able to do any tests that involve the database using a REST client as @Transactional will prevent the data from being saved for the client to get.

To get this to work, @Transactional should not be used. Instead DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD should be used instead. This dramatically slows down each test (as in 1 second to 10 seconds per test) but at least it works.

@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;

    ...

}
Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265