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?
@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 @SpringBootTest – SrThompson@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 test – SrThompson