Reputation: 16281
I want to know if is possible retrieve the ApplicationContext
through a TestRule
.
Here TestRule
is used how an approach to avoid hierarchy among Test Classes, it with the purpose to reuse infrastructure configuration but in this case the structure needed are @Beans
already created by Spring.
To keep simple the code to share, lets suppose we need retrieve the Environment
object.
I have tried these two approaches:
One
@WebAppConfiguration
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
public class ManolitoRule implements TestRule {
@Autowired
private Environment environment;
private static final Logger logger = LoggerFactory.getLogger(ManolitoRule.class.getSimpleName());
@Override
public Statement apply(Statement base, Description description) {
if(environment == null) {
logger.error("NULL");
}
else {
logger.info("Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
}
return new Statement() {
//The @Before configuration should go here now
...
}
};
}
}
And
public class ManolitoTest {
private static final Logger logger = LoggerFactory.getLogger(ManolitoTest.class.getSimpleName());
@Rule
public ManolitoRule manolitoRule = new ManolitoRule();
@Test
public void manolitoTest() {
...
}
}
The environment
is null
Two
public class ManolitoRule implements TestRule {
private final Environment environment;
public ManolitoRule(Environment environment) {
this.environment = environment;
}
private static final Logger logger = LoggerFactory.getLogger(ManolitoRule.class.getSimpleName());
@Override
public Statement apply(Statement base, Description description) {
if(environment == null) {
logger.error("NULL");
}
else {
logger.info("Profiles: {}", Arrays.toString(environment.getActiveProfiles()));
}
return new Statement() {
//The @Before configuration should go here now
....
};
}
}
And
@WebAppConfiguration
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class ManolitoTest {
private static final Logger logger = LoggerFactory.getLogger(ManolitoTest.class.getSimpleName());
@Autowired
private Environment environment;
@Rule
public ManolitoRule manolitoRule = new ManolitoRule(environment);
@Test
public void manolitoTest() {
...
}
}
Again the environment
is null
Does exist a correct configuration to accomplish this configuration?
I have the impression that the life cycles between JUnit
and Spring Framework
are the reason of this situation.
Note: If an abstract class is used all work fine. But consider the scenario to avoid hierarchy and chain @Rule
s, such as ManolitoRule
working with SpringClassRule
and SpringMethodRule
Upvotes: 0
Views: 231
Reputation: 31227
Approach Two is close to a working solution and just needs the following changes.
@RunWith(SpringRunner.class)
.ManolitoRule
as a bean in the test's ApplicationContext
.ManolitoRule
constructor with @Autowired
.manolitoRule
field in the test class with @Rule
and @Autowired
.Note: this technique does not work in conjunction with the Spring rules (SpringClassRule
and SpringMethodRule
). This technique only works in conjunction with the SpringRunner
.
Upvotes: 1
Reputation: 43
have you tried to
@Autowired
private Environment env;
Edit: Try add this as well
@RunWith(SpringJUnit4ClassRunner.class)
Upvotes: 1