使用PowerMock过程中的问题及解决

来源:互联网 发布:南风知我意Ⅰ百度云 编辑:程序博客网 时间:2024/04/30 15:36

1.

下面的异常出现

org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
-> at beyond.tools.util.BeyondExcelUtilsTest.testDoMain(BeyondExcelUtilsTest.java:44)

You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
    when(mock.get(anyInt())).thenReturn(null);
    doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
    verify(mock).someMethod(contains("foo"))

Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().

==》

由于在测试对象的方法前面,@PrepareForTest(测试对象.class)没有追加


2.使用PowerMock,对static方法进行测试的示例
含有STATIC方法的对象(通过PowerMock进行STUB的对象)
public class UtilityClass {

   public static String staticStringMethodWithoutArg() {
        return "";
   }
   
   public static String staticStringMethodWithArg(String arg) {
           return "";
   }
   
   public static String staticStringMethodWithException() {
           return "";
   }
   
   public static void staticVoidMethodWithException() {
           return;
   }

    public static void staticVoidMethodWithArg(List<String> list) {

    }
}需要测试的对象类
public class TargetApp {
    public void doRun() {
        // 不带参数,且有返回的方法
        String returnValue1 = UtilityClass.staticStringMethodWithoutArg();
        System.out.println(returnValue1);
        
        // 带参数,有返回值的方法
        String returnValue2 = Utility.staticStringMethodWithArg("Test data");
        System.out.println(returnValue2);
        
        // 不带参数,且有异常产生的方法
        String returnValue3 = UtilityClass.staticStringMethodWithException();
        System.out.println(returnValue3);

        // 无参数,有异常发生,无返回值的方法
        UtilityClass.staticVoidMethodWithException();
        System.out.println("staticVoidMethodWithException is ok!!");
                
        // 有参数,无返回值的方法
        List<String> strList = new ArrayList<String>();
        strList.add("This");
        strList.add("Is");
        strList.add("A");
        strList.add("Test");
        UtilityClass.staticVoidMethodWithArg(strList);
        System.out.println("staticVoidMethodWithArg is ok!!");        

    }
}对TargetApp进行 测试的类
    public void testUtilityClass() {
        // 调用MOCK的STATIC方法(对STATIC方法时行测试时,必须)
        PowerMockito.mockStatic(UtilityClass.class);
       
        // 确认有返回值时,可以通过以下的三个方法进行测试
        // 无参数的方法
        PowerMockito.when(UtilityClass.staticStringMethodWithoutArg()).thenReturn("Result for staticStringMethodWithoutArg()");
        // 与上面不同之处在参数的传递,(可以传递不同类型的多个参数,参照Machers)
        PowerMockito.when(UtilityClass.staticStringMethodWithArg(Machers.anyString())).thenReturn("Result for staticStringMethodWithArg()");    
       //  返回异常
        PowerMockito.when(UtilityClass.staticStringMethodWithException()).thenThrow(new RuntimeException);    
       
       // 对于VOID方法,可以通过以下的两种类型时行测试
       // 注:
        //   1.对于VOID方法,不能使用上面的方法进行测试
        //   2.以下的方法中,如果将WHEN中的参数,按照上面的格式进行实装时,则会出现编译错误,具体原因不知道。
       //    3.使用下面的方法,需要进行异常处理。否时编译不正确
        try {
            PowerMockito.doThrow(new RuntimeException())when(UtilityClass.class, "staticVoidMethodWithException");
        } catch (Exception ex) {
            
        }    
        // 如果在被MOCK的方法中,需要返回与参数不同值时,就需要使用ANSWER,对参数进行处理,然然返回不同的内容
        // 关于ANSWER的实装,将在以下介绍。
        try {
            PowerMockito.doAnswer(new ArgAnswer()).when(UtilityClass.class, "staticVoidMethodWithArg", Machers.anyList(String.class));
        } catch (Exception ex) {
            
        }
         // 测试对象的调用
        TargetApp app = new TargetApp();
        try {
            app.doRun()
        }catch (Exception ex) {
            
        }
        //  确认以上MOCK方法被调用的次数。
        PowerMockito.veriftyStatic(Mockito.times(1));
        UtilityClass.staticStringMethodWithoutArg();
        UtilityClass.staticStringMethodWithArg("");

        //  如果需要对向MOCK方法中传递的参数进行测试,按如下。
        //  ArgumentCaptor<参数的类型> argument = ArgumentCaptor.forClass(参数的类型.class);
        //  ArgumentCaptor<String> arg1= ArgumentCaptor.forClass(String.class);
        例: staticStringMethodWithArg
        UtilityClass.staticStringMethodWithArg(arg1.capture());
        assertEquals("期望值", argument1.getValue());
    }在被MOCK的方法中,需要对传递来的参数进行修改。(也就是说,在调用MOCK的方法前后,参数的值是不一样的)
public class ArgAnswer implements Answer<List<String>> {

    public List<String> answer(InvocationOnMock invocation) {
        Object args[] = invocation.getArguments(0;
         //取得传递过来的参数,然后可以对参数进行修改。修改方法没有什么特别,此处省略
        List<String> list = (List<String>)args[0];
        return list;
    }
}








原创粉丝点击