美文网首页软件自动化测试
Java_UT_Mock系列之-07 private stati

Java_UT_Mock系列之-07 private stati

作者: antony已经被占用 | 来源:发表于2018-06-25 21:10 被阅读2次

    测试场景

    测试中有遇到一个测试超时的场景。 在系统中配置了一个timeout,默认譬如300S,程序在未达到timeout之前将持续进行。

    如果要测试这个逻辑,就需要等候300S直到退出。对于单元测试来说,这个时间是不可接受的。因此,需要去修改这个private static final 。

    测试代码

    //常量类

    public class Consts {
    
    public static final long TIMEOUT= Long.parseLong("300000");
    
    //public static final long TIMEOUT= 300000L;
    
    public static final int LOGIN_SUCCESS=0;
    
    }
    

    ////SUT

    public class ConstsDemo {
    
    public void longCall() throws Exception {
    
    long begin = System.currentTimeMillis();
    
    while(true) {
    
    if(System.currentTimeMillis()-begin > Consts.TIMEOUT) {
    
    System.out.println("timeout");
    
    throw new Exception("timeout");
    
    }
    
    try {
    
    Thread.sleep(100);
    
    System.out.println(Consts.TIMEOUT);
    
    } catch (InterruptedException e) {
    
    // TODO Auto-generated catch block
    
    e.printStackTrace();
    
    }
    
    }
    
    }
    
    }
    

    // 测试用例

    @RunWith( PowerMockRunner.class )
    
    @PrepareForTest({Consts.class} )
    
    public class ConstsDemoTest {
    
        @Test(expected=Exception.class,timeout=100000)
    
        public void testConsts_TIMEOUT() throws Exception {
    
        spy(Consts.class);
    
            Whitebox.setInternalState(Consts.class, "TIMEOUT", -1L);
    
            ConstsDemo demo= new ConstsDemo();
    
            demo.longCall();
    
        }
    

    这里要注意的问题是, 对于value 为基本类型的无法进行Mock。

    public static final long TIMEOUT= Long.parseLong("300000");
    
    //public static final long TIMEOUT= 300000L;
    

    如果使用 这样的定义,则whitebox将设置成功,但是runtime时无效,因为在JVM 中的不同内存区域。

    即使使用了以下链接提供的反射方法也不行。

    https://stackoverflow.com/questions/5385161/powermock-testing-set-static-field-of-class

    static void setFinalStatic(Class clazz, String fieldName, Object newValue) throws NoSuchFieldException, IllegalAccessException {
    
            Field field = clazz.getDeclaredField(fieldName);
    
            field.setAccessible(true);
    
            Field modifiers = field.getClass().getDeclaredField("modifiers");
    
            modifiers.setAccessible(true);
    
            modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    
            field.set(null, newValue);
    
        }
    

    通过 javap -verbose Consts.class 查看,

    //in-line ,请注意$jacocoInit,表示这段代码可以被jacoco打桩,而基础类型无法注入。 powermock也一样。

    image image

    解决办法

    放弃对于public static final long TIMEOUT= 300000L; 的mock,而转用去Mock以下这个方法,System.currentTimeMillis()

    如以下代码:

    spy(System.class);
    
    when(System.currentTimeMillis()).thenCallRealMethod().thenReturn(Long.MAX_VALUE);
    

    相关文章

      网友评论

        本文标题:Java_UT_Mock系列之-07 private stati

        本文链接:https://www.haomeiwen.com/subject/jeduyftx.html