### Question:
WxCpMessageRouter { public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) { if (isDuplicateMessage(wxMessage)) { return null; } final List<WxCpMessageRouterRule> matchRules = new ArrayList<WxCpMessageRouterRule>(); for (final WxCpMessageRouterRule rule : rules) { if (rule.test(wxMessage)) { matchRules.add(rule); if(!rule.isReEnter()) { break; } } } if (matchRules.size() == 0) { return null; } WxCpXmlOutMessage res = null; final List<Future> futures = new ArrayList<Future>(); for (final WxCpMessageRouterRule rule : matchRules) { if(rule.isAsync()) { futures.add( executorService.submit(new Runnable() { public void run() { rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); } }) ); } else { res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler); log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName()); sessionEndAccess(wxMessage); } } if (futures.size() > 0) { executorService.submit(new Runnable() { @Override public void run() { for (Future future : futures) { try { future.get(); log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName()); sessionEndAccess(wxMessage); } catch (InterruptedException e) { log.error("Error happened when wait task finish", e); } catch (ExecutionException e) { log.error("Error happened when wait task finish", e); } } } }); } return res; } WxCpMessageRouter(WxCpService wxCpService); void setExecutorService(ExecutorService executorService); void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker); void setSessionManager(WxSessionManager sessionManager); void setExceptionHandler(WxErrorExceptionHandler exceptionHandler); WxCpMessageRouterRule rule(); WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage);  }### Answer:
@Test(dataProvider="messages-1") public void testSync(WxCpXmlMessage message, String expected) { StringBuffer sb = new StringBuffer(); WxCpMessageRouter router = new WxCpMessageRouter(null); prepare(false, sb, router); router.route(message); Assert.assertEquals(sb.toString(), expected); }
@Test(dataProvider="messages-1") public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException { StringBuffer sb = new StringBuffer(); WxCpMessageRouter router = new WxCpMessageRouter(null); prepare(true, sb, router); router.route(message); Thread.sleep(500l); Assert.assertEquals(sb.toString(), expected); }