I was wondering about this question by having some trouble writting unit tests for my spring application.
Let's take the following example:
@SpringBootTest
@RunWith(SpringRunner.class)
public class AlbumDTOConverterTest {
@Autowired
private AlbumDTOConverter albumDTOConverter;
@Test
public void ToEntity_ReturnValue_NotNull() {
AlbumDTO albumDTO = new AlbumDTO("Summer album", new Date(), "This summer, we have made some wonderfull photos. Have a look!", null);
assertNotNull(albumDTOConverter.toEntity(albumDTO));
}
}
In order to make @Autowired
work properly, I am launching a container with annotating the test class with @SpringBootTest
.
The thing is that I think I am doing this wrong. In my opinion, I'll rather just create a new instance
of AlbumDTOConverter
by just using the new
operator instead of using Spring's IoD.
What do you guys think about this ?
To check the Service class, we need to have an instance of the Service class created and available as a @Bean so that we can @Autowire it in our test class. We can achieve this configuration using the @TestConfiguration annotation.
1) byName autowiring mode It internally uses setter injection. But, if you change the name of bean, it will not inject the dependency.
If we had used Autowired, we would have been getting the following error in the test. Therefore, it is not recommended to use Autowired. Safety — Forces Spring to provide mandatory dependencies. We make sure that the created objects are valid after construction.
@Inject and @Autowired both annotations are used for autowiring in your application. @Inject annotation is part of Java CDI which was introduced in Java 6, whereas @Autowire annotation is part of spring framework. Both annotations fulfill same purpose therefore, anything of these we can use in our application.
For unit tests you don't need a whole container to start. By definition, such units should be tested in isolation. Creating an instance of a class with the new keyword is perfectly fine. Even if the class has dependencies on other classes, you can also create them manually and pass to an appropriate constructor of the class.
Note that the unit is not the same as the class. The term of the unit is commonly confused among developers, especially beginners. You don't have to rely on the dependency injection in your unit tests. The container will only increase the time needed to execute the tests and the long execution time is the main reason why developers avoid running them very often. There is nothing wrong in manually building your dependency tree for a unit under tests.
In the long run, creating similar inputs for different tests might lead to duplication in the test code, but fortunately there are best practices for this problem, e.g. shared fixture.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With