0
votes

I'm attempting to set up some Spring Boot JPA tests using:

package biz.ianw.coindatabase.test;

@RunWith(SpringRunner.class)
@DataJpaTest     
public class DbTests {
  @Test
  public void test1() { ... }
}

I have a service class:

package biz.ianw.coindatabase.database;

//@Service
@Repository
@Transactional(readOnly=false)
public class CoinDbService { ... }

and an application:

package biz.ianw.coindatabase;

@SpringBootApplication
@Slf4j
@Configuration
@EnableEncryptableProperties
public class Main {
  @Autowired
  CoinDbService dbService;
... }

Starting the test gives the error:

Field dbService in biz.ianw.coindatabase.Main required a bean of type 'biz.ianw.coindatabase.database.CoinDbService' that could not be found.

This is, I assumed, something to do with the type of beans @DataJpaTest loads during startup:

@DataJpaTest can be used if you want to test JPA applications. By default it will configure an in-memory embedded database, scan for @Entity classes and configure Spring Data JPA repositories. Regular @Component beans will not be loaded into the ApplicationContext.

I'm not quite sure why @Service classes should be considered as not required for JPA testing, but I tried to force the matter by annotating it as @Repository instead, but to no avail.

I can manually load the class with @Import(...) but it seems a tad hooky. Is there a better way to tell DataJpaTest what I need for testing?

1
The goal of @DataJpaTest is testing the JPA autoconfiguration, the mappings of your entities, and any Spring Data Repositories that you're using. Services are outside of this scope. If you want an integration test for a Service you need @SpringBootTestSrThompson
SpringBootTest winds up the entire infrastructure, MVC included, which is not what I want for db testing. If all I can test by default with DataJpaTest are the repositories then I'm testing jpa, not my own code.Ian
Not really, you're testing how your code interacts with JPA. You're also testing that any query method that you define in a spring data repository does what you want it to do. Your @Service classes are (should be) at a higher level of abstraction than that, so Spring doesn't consider them part of the scope of @DataJpaTest. To autowire your services you need the full container. You probably could create an alternative Application class that doesn't load the MVC environment and use it as the configuration for your testSrThompson

1 Answers

2
votes

I am quoting from DataJpaTest documentation where you can find the answer to your question.

Annotation that can be used in combination with @RunWith(SpringRunner.class) for a typical JPA test. Can be used when a test focuses only on JPA components.

Using this annotation will disable full auto-configuration and instead apply only configuration relevant to JPA tests.

By default, tests annotated with @DataJpaTest will use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The @AutoConfigureTestDatabase annotation can be used to override these settings.

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.