Junit单元测试+aop+spring+线程池,在进行Junit测试时切面中线程池内调用的方法不执行

一、问题背景:

写了一个切面,指向某service包下的所有类及方法,当该service包下方法被调用时切面执行,切面中用了线程池ExecutorService pool = Executors.newFixedThreadPool(5);线程池内调用了dao层的方法。

二、问题描述:单元测试时,切面中的部分代码执行了,切面中线程池中调用dao的方法没有执行。

三、相关代码:

1、切入点方法代码

public class MyService {
    @Autowired
    private JdbcOperations jdbcTemplate;

    public void m1(UserVo vo) {
        System.out.println("我是m1切入点方法......");
    }

    public void m2(List<UserVo> list) {
        System.out.println("我是m2切入点方法......");
    }
    
    public void m3() {
        System.out.println("我是m3切入点方法......");

    }

}

2、切面类相关代码:

public class ServiceEventAdvice {

private static Logger logger = LoggerFactory.getLogger(ServiceEventAdvice.class);
    
    @Autowired
    private ISaveEvent oracleSaveEvent;
    
    public void before(final JoinPoint jp) throws NoSuchMethodException {
        //打成jar放入到halo框架下需放开下面代码
//        final Map<String, String> map = new HashMap<>();
//        Observable.just(HeaderInfoHolder.getInboundHeader()).subscribe(new Observer<HeaderInfo>() {
//            //从报文头中获取调用方ESB-ORISYS和交易流水号 ESB-TRANNO的值
//            @Override
//            public void onCompleted() {
//                logger.info("观察者HeaderInfo接收数据完毕");
//            }
//
//            @Override
//            public void onError(Throwable e) {
//                logger.info("观察者HeaderInfo接收数据异常");
//            }
//
//            @Override
//            public void onNext(HeaderInfo t) {
//                String orginSystem = ((CxfHeader)t).getOrginSystem();
//                String tcode = ((CxfHeader)t).getTransactionCode();
//                map.put("orginSystem", orginSystem);
//                map.put("tcode", tcode);
//            }
//        });
//        
//        String tcode = map.get("tcode")==null ? "":map.get("tcode");
//        String orginSystem = map.get("orginSystem")==null ? "":map.get("orginSystem");
//        logger.info("本次截获报文头的交易流水号tcode是:" + tcode + ",方法调用方是:" + orginSystem);
        
        System.err.println("对外暴露服务的切面开始执行...");
        String tcode = "tcode";
        String orginSystem = "orginSystem";
        
        Timestamp occurTime = new Timestamp(System.currentTimeMillis());
        String methodName = jp.getSignature().toString();
        Object[] objects = jp.getArgs();
        
        SaveEventVO obj = new SaveEventVO();
        obj.setMethodName(methodName);
        obj.setTcode(tcode);
        obj.setOrginSystem(orginSystem);
        obj.setPtxId("ptxId");
        obj.setBusinessNo("");
        obj.setAopType("A");
        obj.setOccurTime(occurTime);
        
        ExecutorService pool = Executors.newFixedThreadPool(5);
        pool.execute(new Runnable(){
            public void run() {
                byte[] buf = null;
                if (objects.length != 0) {
                    for (Object obj : objects) {
                        if (obj instanceof List<?>) {
                            @SuppressWarnings("unchecked")
                            List<Object> list = (List<Object>) objects[0];
                            buf = SerializeUtil.serializeList(list);
                        }else {
                            buf = SerializeUtil.serializeObject(objects[0]);
                        }
                    }
                }
                System.out.println("11111111111");
                oracleSaveEvent.save(buf,obj);//在单元测试中,该行代码没有执行
                System.out.println("222222222222");//在单元测试中,该行代码没有执行

            }
            
        });
        
    }
    
    
}

3、单元测试类代码:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:generalevent/applicationContext-generalevent.xml"})
public class MyServiceTest {
    
    @Autowired
    MyService myService;
    @Autowired
    ISaveEvent saveEvent;
    
    @Test
    public void myServiceTest(){
        System.err.println("myService=" + myService + ",saveEvent="+ saveEvent);
        Address address1 = new Address("addr111", "beijing");
        Address address2 = new Address("addr222", "shanghai");
        UserVo vo = new UserVo("a123", "lsl", 21,address1);
        UserVo vo2 = new UserVo("b456", "mjx", 21,address2);
        List<UserVo> list = new ArrayList<UserVo>();
        list.add(vo);
        list.add(vo2);
        myService.m2(list);
       
        
    }

4 、运行结果截图:

四、问题原因

在做单元测试时,切面中线程池中的线程还没有开始启动,而主线程已经关闭了,造成切面类中标颜色的两行代码没有执行。

五、解决办法

在单元测试方法中最后加入一行代码:System.in.read();,不让主线程关闭。就ok了。即标色部分:

@Test
    public void myServiceTest(){
        System.err.println("myService=" + myService + ",saveEvent="+ saveEvent);
        Address address1 = new Address("addr111", "beijing");
        Address address2 = new Address("addr222", "shanghai");
        UserVo vo = new UserVo("a123", "lsl", 21,address1);
        UserVo vo2 = new UserVo("b456", "mjx", 21,address2);
        List<UserVo> list = new ArrayList<UserVo>();
        list.add(vo);
        list.add(vo2);
        myService.m2(list);
        try {
            System.in.read();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        
    } 

猜你喜欢

转载自blog.csdn.net/dhklsl/article/details/83621298
今日推荐