I am studying for the Spring Core certification and I have the following problem with an exercise related to the use of JUnit test in Spring.
So I have the following configuration class named TestInfrastructureConfig
:
@Configuration
@Import({
TestInfrastructureDevConfig.class,
TestInfrastructureProductionConfig.class,
RewardsConfig.class })
public class TestInfrastructureConfig {
public LoggingBeanPostProcessor loggingBean(){
return new LoggingBeanPostProcessor();
}
}
This class configure the test environment-
Now in an exercise say that:
In Spring when no configuration class or configurationXML file is specified,
@ContextConfiguration
will look for an inner class marked with@Configuration
(If none is found it will also look for an XML file name of<Classname>
-context.xml). Since theTestInfrastructureConfig
class is so small anyway, copy the entire class definition, including annotations, to an inner class withing the test class. Then remove the configuration class reference from the@ContextConfiguration
annotation (no property in the brackets). This is an example of convention over configuration.
So I have totally commentd the code of the TestInfrastructureConfig
class that become:
//package rewards;
//
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Import;
//
//import config.RewardsConfig;
//
//@Configuration
//@Import({
// TestInfrastructureDevConfig.class,
// TestInfrastructureProductionConfig.class,
// RewardsConfig.class })
//public class TestInfrastructureConfig {
//
// public LoggingBeanPostProcessor loggingBean(){
// return new LoggingBeanPostProcessor();
// }
//}
Then in the RewardNetworkTests
I change:
@ContextConfiguration(classes=TestInfrastructureConfig.class)
into:
@ContextConfiguration()
and I add the code of the commented TestInfrastructureConfig
into the RewardNetworkTests
class as an inner class, something like this:
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes=TestInfrastructureConfig.class)
@ContextConfiguration()
//@ActiveProfiles("jdbc")
//@ActiveProfiles({ "jdbc", "jdbc-dev" })
@ActiveProfiles({ "jdbc", "jdbc-production" })
public class RewardNetworkTests {
/**
* The object being tested.
*/
@Autowired
private RewardNetwork rewardNetwork;
@Test
public void testRewardForDining() {
// create a new dining of 100.00 charged to credit card
// '1234123412341234' by merchant '123457890' as test input
Dining dining = Dining.createDining("100.00", "1234123412341234",
"1234567890");
// call the 'rewardNetwork' to test its rewardAccountFor(Dining) method
RewardConfirmation confirmation = rewardNetwork
.rewardAccountFor(dining);
// assert the expected reward confirmation results
assertNotNull(confirmation);
assertNotNull(confirmation.getConfirmationNumber());
// assert an account contribution was made
AccountContribution contribution = confirmation
.getAccountContribution();
assertNotNull(contribution);
// the contribution account number should be '123456789'
assertEquals("123456789", contribution.getAccountNumber());
// the total contribution amount should be 8.00 (8% of 100.00)
assertEquals(MonetaryAmount.valueOf("8.00"), contribution.getAmount());
// the total contribution amount should have been split into 2
// distributions
assertEquals(2, contribution.getDistributions().size());
// each distribution should be 4.00 (as both have a 50% allocation)
assertEquals(MonetaryAmount.valueOf("4.00"), contribution
.getDistribution("Annabelle").getAmount());
assertEquals(MonetaryAmount.valueOf("4.00"), contribution
.getDistribution("Corgan").getAmount());
}
@Configuration
@Import({
TestInfrastructureDevConfig.class,
TestInfrastructureProductionConfig.class,
RewardsConfig.class })
public class TestInfrastructureConfig {
public LoggingBeanPostProcessor loggingBean(){
return new LoggingBeanPostProcessor();
}
}
}
But when I try to run the test I obtain the red bar, the test is not passed, and the following error message:
java.lang.IllegalStateException: Neither GenericXmlContextLoader nor AnnotationConfigContextLoader was able to detect defaults, and no ApplicationContextInitializers were declared for context configuration [ContextConfigurationAttributes@52d455b8 declaringClass = 'rewards.RewardNetworkTests', locations = '{}', classes = '{}', inheritLocations = true, initializers = '{}', inheritInitializers = true, name = [null], contextLoaderClass = 'org.springframework.test.context.ContextLoader']
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.processContextConfiguration(AbstractDelegatingSmartContextLoader.java:200)
at org.springframework.test.context.ContextLoaderUtils.buildMergedContextConfiguration(ContextLoaderUtils.java:703)
at org.springframework.test.context.ContextLoaderUtils.buildMergedContextConfiguration(ContextLoaderUtils.java:656)
at org.springframework.test.context.DefaultTestContext.<init>(DefaultTestContext.java:93)
at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:122)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:118)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:107)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Why? What could be the problem? How can I try to solve this issue?
I think your
LoggingBeanPostProcessor
method needs the@Bean
annotation, not sure if that will solve the issue though