Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better to use @Autowired or new in Spring test class?

Tags:

java

junit

spring

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 ?

like image 466
MadJlzz Avatar asked Nov 18 '16 10:11

MadJlzz


People also ask

Can we use @autowired in test class?

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.

Which Autowiring is better in spring?

1) byName autowiring mode It internally uses setter injection. But, if you change the name of bean, it will not inject the dependency.

Why is Autowired not recommended?

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.

Should I use Autowired or inject?

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


1 Answers

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.

like image 109
Daniel Olszewski Avatar answered Sep 25 '22 13:09

Daniel Olszewski