有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在参数上调用方法时,java PowerMockito mocking静态方法失败

我试着测试一个类,它使用一个计算器类和一些静态方法。我已经用类似的方式成功地模仿了另一个类,但这个类被证明更顽固

如果mock方法包含对传入参数之一的方法调用,静态方法似乎不会被mock(测试中断)。取消内部通话显然不是一种选择。我有什么明显的遗漏吗

这是一个浓缩版本,其行为方式与

public class SmallCalculator {

    public static int getLength(String string){

        int length = 0;

        //length = string.length(); // Uncomment this line and the mocking no longer works... 

        return length;
    }
}

这是测试

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class SmallTester {

    @Test
    public void smallTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        assertEquals(5, SmallCalculator.getLength(""));
    }
}

这个问题似乎有些混乱,所以我设计了一个更“现实”的例子。这一个增加了一个间接层次,所以看起来我不是在直接测试模拟方法。SmallCalculator类保持不变:

public class BigCalculator {

    public int getLength(){

        int length  = SmallCalculator.getLength("random string");

        // ... other logic

        return length;
    }

    public static void main(String... args){

        new BigCalculator();
    }
}

这是新的测试课程

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.solveit.aps.transport.model.impl.BigCalculator;
import com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {

    @Test
    public void bigTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        BigCalculator bigCalculator = new BigCalculator();
        assertEquals(5, bigCalculator.getLength());
    }
}

共 (2) 个答案

  1. # 1 楼答案

    首先,删除该行:

    given(SmallCalculator.getLength(any(String.class))).willReturn(5);

    因为你在测试同样的方法。你不想嘲笑你正在测试的方法

    其次,将注释修改为:

    @PrepareForTest({ SmallCalculator.class, String.class})
    

    最后,为长度()添加模拟;像这样:

    given(String.length()).willReturn(5);
    

    我想可以;)

  2. # 2 楼答案

    anyString()代替any(String.class)

    当使用any(String.class)时,传递的参数是null,因为Mockito将返回引用类型的默认值,即null。结果你得到了一个例外

    使用anyString()时,传递的参数将是空字符串

    请注意,这解释了为什么会出现异常,但是您需要查看测试方法的方式,如其他注释和答案中所述