Reputation: 1817
I have @Service in Spring Boot app which is parsing file and then storing it into DB using Spring Data JPA. I want to test this parsing with all logic of changing this mapping. So, for this I need to store mapping in DB in test.
@Service
public class ParsingService {
@Autowired
private StoringInDBRepository storingInDBRepository;
}
@Repository
public interface StoringInDBRepository extends JpaRepository<MyEntity, String> {
The problem is that during test with annotation @SpringBootTest I don't want to load the whole context, but only my ParsingService. When I writing :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ParsingService.class})
public class ParsingServiceTest{
@Test
public void someTest(){
}
}
This test couldn't be initialized because I am not loading StoringInDBRepository in @SpringBootTest annotation. However I can do it, because StoringInDBRepository is an interface. Usage of @DataJpaTest according to javadoc will be correct only if I'm testing repository layer. Usage of @DataJpaTest and @SpringBootTest is not recommended.
How should I test such services? Thanks in advance.
Upvotes: 3
Views: 3307
Reputation: 1817
So, after all investigations I found a couple solutions. I chose to enable repositories and service with
@SpringBootTest(classes = {ParsingService.class})
@EnableJpaRepositories(basePackages = "com.my.repository")
@EntityScan("com.my.entity")
@AutoConfigureDataJpa
This is a workaround. And I don't think it is the best. The other solution is to create a @TestConfiguration which will return your service and all to use @DataJpaTest annotation to enable repository classes. In this case you should use @SpringBootTest annotation
Upvotes: 5
Reputation: 3814
You could use a @SpyBean
to get what you want. It is fairly easy to use.
However - You don't actually need to test it in that way. Because by having your application context tested, you are making sure all classes get injected/autowired as they should be. Then separately test the method on the service level with mocks. And lastly, use @DataJpaTest
to test it in the repository/DB level.
So you decouple your tests nicely: integration tests / unit tests / repository tests
There is no need to tightly couple all those three things in one class or test method.
Upvotes: 2