Reputation: 77
I'm wrting a JUnit to test a threshold value, which is passed from a .properties
file like:
threshold=8
And I use a spring context to apply this threshold value:
<context:property-placeholder location="classpath:test.properties"/>
<si:channel id="thresholdInputChannel"/>
<si:recipient-list-router input-channel="thresholdInputChannel" default-output-channel="nullChannel">
<si:recipient channel = "recipientChannel" selector-expression = "${threshold} > 0"/>
</si:recipient-list-router>
...
<si:chain input-channel = "fileTransformationChannel" output-channel="endChannel">
<si:transformer method = "transform">
<bean class = "fileTransformer" >
<property name = "fixedProperties">
<map>
<entry key="threshold" value="${threshold}"/>
</map>
</property>
</bean>
</si:transformer>
</si:chain>
...
Before in the JUnit test, I used @ContextConfiguration(locations = {"classpath:test.properties"})
to load the context and @RunWith(SpringJUnit4ClassRunner.class)
and @Autowired
to get all the channels defined in context file and it worked fine. But the problem is that like this I can test at one time one single value of ${threshold}
which is predefined in the test.properties
.
To be able to change ${threshold}
value, I tried all the ways mentioned in this answer:
Use @RunWith(Parameterized.class)
@Parameterized.Parameters
public static List<Object[]> params() {
return Arrays.asList(new Object[][]{
{"0"},
{"8"},
});
}
but in this way I can't use injected beans any more, hence I lost the channels in JUnit.
public abstract class AbstractJunitTest extends AbstractJUnit4SpringContextTests
same problem with injected beans.
@Value("${threshold}")
private String threshold;
origin value don't get erased and invoke a problem of variable type as there is selector-expression = "${threshold} > 0"
in context file.
I'd like to know if there is any other possible ways to do this. Dropping the context file and creating an ApplicationConfig.class
with all the beans and parameters may be a solution but not a prefered one, as the context file is really great.
By the way, the reason I have to autowire the channels in JUnit is that I have to send a local file into the fileTransformationChannel
and get it transformed in some way.
Upvotes: 0
Views: 1468
Reputation: 883
you can use org.springframework.test.context.TestContextManager for this:
Exemple:
@RunWith(Parameterized.class)
@SpringBootTest(classes = Application.class)
public class TargetClassTest {
@Autowired
private TargetClass instance;
private TestContextManager testContextManager;
String threshold;
@Before
public void setUpContext() throws Exception {
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
}
@Parameters
public static Collection<Object []> data() {
return Arrays.asList(new Object[][]{
{"0"},{"8"},
});
}
public TargetClassTest(String test) {
this.threshold = test;
}
@Test
public void testSomething() throws Exception {
String r = instance.businessMethod(threshold);
Assert.assertEquals(threshold, r);
}
}
In this case, it is possible after the initialization of @Before "inject" your Spring bean and use the parameterized execution to test several scenarios.
Upvotes: 1