• 简单介绍如何使用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
  • 相关阅读:
    无root权限安装tmux
    mosquitto_pub和mosquitto_sub 命令参数说明
    安装Mosquitto学习MOTT协议
    Linux之prink原理
    JZ2440支持设备树(1)-添加设备树之后kernel的启动参数跟dts里面不一致
    Linux可以生产uImage
    Ubuntu18.04下make menuconfig缺少ncurses库
    如何打开kernel最开始的打印
    buildroot管理uboot+kernel+rootfs
    STM32L071CBTX操作ECC508
  • 原文地址:https://www.cnblogs.com/softidea/p/5157362.html
Copyright © 2020-2023  润新知