当前位置: 首页 > 知识库问答 >
问题:

用PowerMockito模拟getClass方法

夏俊人
2023-03-14
public class ClassToTest {
    /** Map that will be populated with objects during constructor */
    private Map<Class<?>, Method> map = new HashMap<Class<?>, Method>();

    ClassToTest() {
        /* Loop through methods in ClassToTest and if they return a boolean and 
           take in an InterfaceA parameter then add them to map */
    }

    public void testMethod(InterfaceA obj) {
        final Method method = map.get(obj.getClass());
        boolean ok;
        if (method != null) {
             ok = (Boolean) method.invoke(this, obj);
        }
        if (ok) {
            obj.run();
        }
    }

    public boolean isSafeClassA(final ClassA obj) {
        // Work out if safe to run and then return true/false
    }

    public boolean isSafeClassB(final ClassB obj) {
       // Work out if safe to run and then return true/fals 
    }

}

public interface InterfaceA {
   void run()
}

public class ClassA implements InterfaceA {
   public void run() {
      // implements method here
   }
}

public class ClassB implements InterfaceA {
    public void run() {
       // implements method here
    }
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassA.class})
public class ClassToTestTest {
    private final ClassToTest tester = new ClassToTest();

    @Test
    public void test() {
        MockGateway.MOCK_GET_CLASS_METHOD = true;
        final ClassA classA = spy(new ClassA());
        doReturn(ClassA.class).when(classA).getClass();
        MockGateway.MOCK_GET_CLASS_METHOD = false;

        tester.testMethod(classA);
        verify(classA).run();
    }
}

提前谢了。

共有1个答案

柴衡
2023-03-14

您的问题实际上是getclassobject中的final,所以您不能用mockito来存根它。我想不出一个好办法来解决这个问题。有一种可能性,你可以考虑一下。

编写具有单个方法的实用程序类

public Class getClass(Object o){
    return o.getClass();
}

重构您正在测试的类,以便它使用这个实用工具类的对象,而不是直接调用getclass()。然后,可以使用特殊的包私有构造函数或setter方法注入实用工具对象。

public class ClassToTest{
    private UtilityWithGetClass utility;
    private Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();

    public ClassToTest() {
        this(new UtilityWithGetClass());
    }

    ClassToTest(UtilityWithGetClass utility){
        this.utility = utility;
        // Populate map here
    }

    // more stuff here
}
 类似资料: