zoukankan      html  css  js  c++  java
  • 简单介绍如何使用PowerMock和Mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值(转)

    本文将简单介绍如何使用PowerMock和Mockito来mock
    1. 构造函数
    2. 静态函数
    3. 枚举实现的单例
    4. 选择参数值做为函数的返回值
    5. 在调用mock出来的方法中,改变方法参数的值

    一点简要说明:Mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例。但是这种实现方式不能用于构造函数和静态函数,因为那需要使用类的字节码(比如使用javassist). 所以我们才需要结合使用PowerMock.

    1. mock构造函数, 如果有代码没有使用DI注入依赖实例,在单元测试中可以使用PowerMock来模拟创建对象。
    注意的开始两行的2个注解 @RunWith 和 @PrepareForTest
    @RunWith比较简单,后面始终是PowerMockRunner.class
    @PrepareForText后面需要加的是调用构造函数的类名,而不是有构造函数的类本身。
    在下面的例子中,我们要测试的类是:Helper, 在Helper类中调用了Somthing类的构造函数来创建实例。

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Helper.class)
    public class HelperTest {
      @Mock
      private Something mockSomething;
          
      @InjectMocks
      private Helper helper;
          
      @Test
      public void doSomething() throws Exception {
          String argument = "arg";
              
          PowerMockito.whenNew(Something.class).withArguments(argument).thenReturn(mockSomething);//mock静态字段时,也可以使用此方法
              
          // 调用需要测试方法
          helper.doSomething(argument);
              
          // 进行验证
          verify(mockSomething).doIt();
      }
    }


    public class Helper {
      public void doSomething(String arg) {
          Something something = new Something(arg);
          something.doit();
      }
    }


    2,mock 静态函数, 单例模式就是一个典型的会调用静态函数的例子。 注意要点与mock构造函数相同。

    class ClassWithStatics {
      public static String getString() {
        return "String";
      }

      public static int getInt() {
        return 1;
      }
    }

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(ClassWithStatics.class)
    public class StubJustOneStatic {
      @Test
      public void test() {
        PowerMockito.mockStatic(ClassWithStatics.class);

        when(ClassWithStatics.getString()).thenReturn("Hello!");

        System.out.println("String: " + ClassWithStatics.getString());
        System.out.println("Int: " + ClassWithStatics.getInt());
      }
    }


    3。mock枚举实现的单例

    SingletonObject.java 
    public enum SingletonObject { 
        INSTANCE;
        private int num;
        protected void setNum(int num) {
            this.num = num;
        }
        public int getNum() {
            return num;
        }
    }
    SingletonConsumer.java

    public class SingletonConsumer { 
        public String consumeSingletonObject() { 
            return String.valueOf(SingletonObject.INSTANCE.getNum());
        }
    }
    SingletonConsumerTest.java
    @RunWith(PowerMockRunner.class) 
    @PrepareForTest({SingletonObject.class})
    public class SingletonConsumerTest {
        @Test public void testConsumeSingletonObject() throws Exception {
            SingletonObject mockInstance = mock(SingletonObject.class);
            Whitebox.setInternalState(SingletonObject.class, "INSTANCE", mockInstance);
            when(mockInstance.getNum()).thenReturn(42);
            assertEquals("42", new SingletonConsumer().consumeSingletonObject());
        }
    }

    4。返回参数值做为函数返回值。
    mockito 1.9.5之后,提供一个方便的方法来实现这个需要,在这之前可以使用一个匿名函数来返回一个answer来实现。

    when(myMock.myFunction(anyString())).then(returnsFirstArg());

    其中returnsFirstArg()是org.mockito.AdditionalAnswers中的一个静态方法。
    在这个类中还有其他的一些类似方法
    returnsSecondArg()

    returnsLastArg()
    ReturnsArgumentAt(int position)
    5. 在调用mock出来的方法中,改变方法参数的值
    when( myMock.someMethod( any( List.class ) ) ).thenAnswer( ( new Answer<Void>() {
        @Override
        public Void answer( InvocationOnMock invocation )
                throws Throwable {
            Object[] args = invocation.getArguments();
            List arg1 = (List)args[0];
            arg1.add("12345");
            return null;
        }
    } ) );



    Verifying with generic parameters
    verify(someService).process(Matchers.<Collection<Person>>any());
    verify(adunoMasterBaseProcessor).processBinFiles( anyListOf(File.class) );
    http://www.blogjava.net/usherlight/archive/2015/06/16/425740.html
  • 相关阅读:
    计算机组成原理期末第十章【计算部分】
    计算机组成原理期末第六章【计算部分】
    快速傅里叶变换总结
    Graph 题解
    NOI 赛前复习旧题 & 复习知识点计划
    Party 题解
    洛谷 P7054 [NWRRC2015]Graph 题解
    CF1542D Priority Queue 题解
    Codeforces Round #701 (Div. 2) E. Move and Swap
    常微分方程
  • 原文地址:https://www.cnblogs.com/softidea/p/5157362.html
Copyright © 2011-2022 走看看