Sam
Sam

Reputation: 191

Error Could not open ServletContext resource in jUnit Testing Spring Integration

I am new to Spring Integration and I am trying to test the channel. I have written a below code. but i am getting exception while testing it. Please help me in resolving that.

Spring Integration flow.

<int:channel id="reqGetAllMedChannel" />
<int:channel id="resGetAllMedChannel" />
<int-http:inbound-gateway
    request-channel="reqGetAllMedChannel"
    reply-channel="resGetAllMedChannel" supported-methods="GET"
    path="/getAllMedicines">

    <int-http:request-mapping
        consumes="application/json" produces="application/json" />
</int-http:inbound-gateway>


<int:service-activator
    ref="medicineServiceActivator" method="getAllMedicines"
    input-channel="reqGetAllMedChannel"
    output-channel="resGetAllMedChannel" />

Method which is getting invoked.

public Message<List<Medicine>> getAllMedicines() {
    log.info("GET request for Medicine");
    List<Medicine> medLst = medicineService.getAllMedicines();
    return MessageBuilder.withPayload(medLst).setHeader("http_statusCode", HttpStatus.OK).build();
}

Testing xml configuration

<import resource="classpath:medicineIntegration.xml"/>

<int:bridge input-channel="resGetAllMedChannel" output-channel="testOutput">
</int:bridge>

<int:channel id="testOutput">
<int:queue/>
</int:channel>

jUnit test case.

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(locations= {"classpath*:Integration-Test.xml"})
public class MessageChannelTest {

@Autowired
private MessageChannel inputChannel;

@Autowired
private QueueChannel testChannel;

@Mock
private MedicineService medicineService;

@Test
public void testChannel() {
    List<Medicine> medicines = new ArrayList<Medicine>();
    Medicine medicine1 = new Medicine();
    medicine1.setMedName("Crocine");
    medicine1.setExpDate("01-01-2020");
    Medicine medicine2 = new Medicine();
    medicine2.setMedName("Paracetamole");
    medicine2.setExpDate("02-02-2020");
    medicines.add(medicine1);
    medicines.add(medicine2);
    when(medicineService.getAllMedicines()).thenReturn(medicines);
    inputChannel.send(MessageBuilder.withPayload("").build());
    Message<?> outMsg = testChannel.receive(1000);
    assertThat(medicineService).isEqualTo(outMsg.getPayload());
}
}

Below is the exception i am getting while testing the jUnit code. Please help me and let me know if i am doing something wrong.

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ~[junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) ~[junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) ~[junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) ~[junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) ~[junit-4.12.jar:4.12]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) ~[junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) ~[junit-4.12.jar:4.12]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89) ~[.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) ~[.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541) ~[.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763) ~[.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463) ~[.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209) ~[.cp/:na]

Upvotes: 0

Views: 440

Answers (2)

Artem Bilan
Artem Bilan

Reputation: 121427

According the exception your medicineService depends on the MedicineRepository. Since you just have a:

@Mock
private MedicineService medicineService;

You don't effect the application context and don't replace your medicineService bean definition.

If you really want just mock this MedicineService and replace it in the application context, you should consider to use a @MockBean from Spring Boot: https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-testing-spring-boot-applications-mocking-beans

You also can just @MockBean for that MedicineRepository and your MedicineService will remain the same in the application context.

I have already suggested you something similar in other your question: JUnit for Spring Integration Activator with return type Message<?>

Upvotes: 1

Ori Marko
Ori Marko

Reputation: 58812

MedicineRepository is part of the mocked service, try adding it to test context using @Spy and @Autowired:

@Autowired
@Spy
MedicineRepository medicineRepository

Upvotes: 0

Related Questions