I am integration testing a spring integration flow, which starts with a Mail inbound channel adapter. I send test emails to a mock GreenMail email server and then test the expected outcome. But because the email is asynchronous, the test currently only passes if I wait after sending the mail, until the flow completes.
Here is the mail adapter config:
<int-mail:inbound-channel-adapter id="imapAdapter"
store-uri="#{mailConnectionString}"
java-mail-properties="javaMailProperties" channel="inboundChannel"
should-delete-messages="false" should-mark-messages-as-read="true"
auto-startup="true">
<int:poller id="emailPoller" max-messages-per-poll="1" fixed-rate="5000">
</int:poller>
</int-mail:inbound-channel-adapter>
So, with reference to this: Adding Completion Advice, I thought I could simply wait for the completion advice and then continue testing. But you can't add advice to the mail adapter:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'adviceChain' of bean class [org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean]: Bean property 'adviceChain' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Also tried the reply producing handler (from above link), but no bean was found.
So. How do I add advice to the inbound mail adapter? Or is there a better way to test the mail adapter once the entire flow completes?
Update after answer suggestion I changed the test to add the advice within the set up.
@Autowired
private SourcePollingChannelAdapter emailAdapter;
private MyAdvice imapAdapterCompletionAdvice;
@Before
public void setup() throws Exception
{
imapAdapterCompletionAdvice = new MyAdvice();
List<Advice> theAdvice = new ArrayList<Advice>();
theAdvice.add(imapAdapterCompletionAdvice);
emailAdapter.setAdviceChain(theAdvice);
emailAdapter.start();
}
But the advice is not called. Am I missing something?
Here is the Advice class:
public class MyAdvice implements MethodInterceptor {
private final CountDownLatch latch = new CountDownLatch(1);
public Object invoke(MethodInvocation invocation) throws Throwable {
Object proceed = invocation.proceed();
System.out.println(proceed);
if (proceed instanceof Boolean) {
Boolean mailReceived = (Boolean) proceed;
if(mailReceived){
latch.countDown();
}
}
return proceed;
}
public CountDownLatch getLatch() {
return latch;
}
}