Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何解决异步线程不生效的问题 #18

Open
sfomp opened this issue Jun 12, 2019 · 4 comments
Open

如何解决异步线程不生效的问题 #18

sfomp opened this issue Jun 12, 2019 · 4 comments

Comments

@sfomp
Copy link

sfomp commented Jun 12, 2019

主线程中进行了mock静态方法,但是在主线程中待测试的代码中又启了新的线程,新的线程中也用到了前面mock的对象,但实际上获取不到值。这种情况如何解决。理论上jmockit也是用到了instrument的技术,内置的transformer生成的字节码会重新加载才对啊,对所有线程都是可用的。

@before
public void before() {
message = new CacheMessage();

    byte[] msgByte = {1,2};
    message.setIsEncrypt(false);
    message.setMessageByte(msgByte);
    message.setStatus("15");
    message.setAppId(10000);
    message.setPushTime(1);
    message.setDataFrom(103);
    message.setPushType(1);
    message.setExpireTime(new Date(System.currentTimeMillis() + 1000000L));
    message.setMd5("");
    message.setMessageBizType(1);
    message.setMessageType(5);
    message.setAppType(1);

    clientInfo = getMockClientInfo(1L);

    new NonStrictExpectations(SpringUtils.class) {
        {
            SpringUtils.getBean("localCachePool");
            result = localCachePool;
            times = 10;

.....

@Test
public void testPublish() {

    PushServantImpl pushServant = new PushServantImpl();
    pushServant.sendByClientId(1, 1, PushType.ONE_REGID_PUSH.value);
}

pushServant里面有异步处理逻辑,异步的这句 localCachePool = SpringUtils.getBean("localCachePool");实际是取不值。

@hzdavid
Copy link
Owner

hzdavid commented Jun 12, 2019

你是说localCachePool = SpringUtils.getBean("localCachePool") ,你拿的localCachePool为null?

@sfomp
Copy link
Author

sfomp commented Jun 13, 2019

你是说localCachePool = SpringUtils.getBean("localCachePool") ,你拿的localCachePool为null?
是的,在Test类的当前线程里面是可以拿到 SpringUtils.getBean("localCachePool") 的实例,localCachePool已经通过Mocked注解。
@mocked
LocalCachePool localCachePool;
但是异步线程里面拿不到,理论上字节码会重新加载的。

@sfomp
Copy link
Author

sfomp commented Jun 13, 2019

你是说localCachePool = SpringUtils.getBean("localCachePool") ,你拿的localCachePool为null?
是的,在Test类的当前线程里面是可以拿到 SpringUtils.getBean("localCachePool") 的实例,localCachePool已经通过Mocked注解。
@mocked
LocalCachePool localCachePool;
但是异步线程里面拿不到,理论上字节码会重新加载的。
另外的类,我通过反射给localCachePool设置一个自定义的filed,调试的时候发现可以看到这个filed,但是实际运行的时候不执行clientCache的createNewClientInfo方法,但是如果写成: LocalCachePool localCachePool = new LocalCachePool ();就可以
@mocked
LocalCachePool localCachePool;

比如:
buildCache();
Field field = localClientCache.getClass().getDeclaredField("localClientCache");
field.setAccessible(true);
field.set(localClientCache, clientCache);
receiverToPusherServant.reportCtl(list);
LocalClientInfo clientInfo1 = localClientCache.getClientInfo("1");
Assert.assertTrue("md5v".equals(clientInfo1.getControlInfo().getMd5Validity().get("md5")));
}

private void buildCache() {
    clientCache = Caffeine.newBuilder()
            .expireAfterAccess(1, TimeUnit.DAYS)
            .maximumSize(1)
            .build(clientId -> createNewClientInfo(clientId));
}

private LocalClientInfo createNewClientInfo(Long clientId) {
return new LocalClientInfo();
}

@hzdavid
Copy link
Owner

hzdavid commented Jun 18, 2019

@sfomp 异步线程 是通过jdk自带线程池启动的,还是直接new Thread

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants