Considering that SF since 4.3 @Autowired
is not necessary to be declared explicitly in a contructor when in the class exists only one constructor.
Consider the following
@ActiveProfiles({"pre-prod","cache"})
@SpringJUnitConfig(classes={AppConfig.class})
@DisplayName("Testing Multiple 'reporte' Test Methods")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class CientificoServiceReporteTests {
@Autowired
private CientificoService cientificoService;
@Autowired
private ConfigurableApplicationContext ctx;
@Autowired
private Environment env;
@Test
@Order(1)
@DisplayName("Testing Reporte - 'findById'")
void reporteFindByIdTest() {
...
}
...
}
It works as expected. Furthermore I know that is not wise use @Autowired
in an instance variable for a business classes such as @Service
and @Repository
, but is valid for @Configuration
and Test classes.
Could you consider in "create" something like this:
@AutowiredTest
@ActiveProfiles({"pre-prod","cache"})
@SpringJUnitConfig(classes={AppConfig.class})
@DisplayName("Testing Multiple 'reporte' Test Methods")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class CientificoServiceReporteTests {
private CientificoService cientificoService;
private ConfigurableApplicationContext ctx;
private Environment env;
@Test
@Order(1)
@DisplayName("Testing Reporte - 'findById'")
void reporteFindByIdTest() {
...
}
...
}
Observe that is not used @Autowired
anymore in the instance variables but is declared @AutowiredTest
at class level.
The point is: if a Test class has at class level @AutowiredTest
declared then Spring Framework should apply Autowiring automatically for each instance variable declared. This idea brought me a student and he did mention it is possible in Python.
What do you think?
Comment From: sbrannen
Hi @manueljordan,
Thanks for the suggestion.
Unfortunately, introducing such an annotation/mechanism could likely lead to issues for use cases where a test class contains other fields that cannot be autowired from a Spring ApplicationContext
-- for example, @TempDir
fields, fields that track some form of state within the test class, mocks, etc.
In light of that, we do not plan to add such a feature.
However, with JUnit Jupiter based tests, you always have the option of autowiring the constructor.
For example, you could write your example as follows.
@SpringJUnitConfig(AppConfig.class)
class CientificoServiceReporteTests {
private final CientificoService cientificoService;
private final ConfigurableApplicationContext ctx;
private final Environment env;
@Autowired
CientificoServiceReporteTests(CientificoService cientificoService,
ConfigurableApplicationContext ctx) {
this.cientificoService = cientificoService;
this.ctx = ctx;
this.env = ctx.getEnvironment();
}
@Test
@DisplayName("Testing Reporte - 'findById'")
void reporteFindByIdTest() {
// ...
}
// ...
}
And if you annotate your test class with @TestConstructor(autowireMode = ALL)
or change the default test constructor autowire mode to ALL, you can omit @Autowired
on the constructor.
See the section on Constructor Injection in the reference manual for further details.
Comment From: manueljordan
Hello @sbrannen
Thanks for the reply and feedback. Understood. I am going to check this set of annotations to see some samples in action.