2019-03-29 Mockito初探

2019-03-29  本文已影响0人  DoubleFooker

Mockito初探

Mockito 可以改变一个类或者对象的行为,能够让我们更加专注地去测试代码逻辑,省去了构造测试数据所花费的努力。

参考阅读

概念介绍

MOCK

import static org.mockito.Mockito.*;
public class MockitoTest {   
    @Test
    public void test() {
        //Mock:定义Class Mock对象,这里返回的mockedList完全失去了原来的行为
        List mockedList = mock(List.class);
        //Stub:未定义,返回默认值false
        System.out.println(mockedList.add("a"));
       //校验Stub行为合法性。如果是add("b"),则不通过。因为没有定义add("b")的行为
        verify(mockedList).add("a");
    }

    @Test
    public void spytest() {
        List list = new LinkedList();
        //定义Partial Mock 实例Mock对象
        List spy = spy(list);
        //定义stub返回false
        when(spy.add("a")).thenReturn(false);
        //返回false 定义了stub
        System.out.println(spy.add("a"));
        //为定义add("b")行为,则调用真实方法
        System.out.println(spy.add("b"));
        //校验
        verify(spy).add("a");
    }
}

mock源码

1:
@CheckReturnValue
public static <T> T mock(Class<T> classToMock) {
//注意withSettings,配置默认返回方式为返回java相关类型的默认值
    return mock(classToMock, withSettings());
}
@CheckReturnValue
public static MockSettings withSettings() {
    return new MockSettingsImpl().defaultAnswer(RETURNS_DEFAULTS);
}
2:
@CheckReturnValue
public static <T> T mock(Class<T> classToMock, MockSettings mockSettings) {
    return MOCKITO_CORE.mock(classToMock, mockSettings);
}                               

spy源码

   @CheckReturnValue
    public static <T> T spy(T object) {
        return MOCKITO_CORE.mock((Class<T>) object.getClass(), withSettings()
                .spiedInstance(object)
                 //默认执行对象的真实方法
                .defaultAnswer(CALLS_REAL_METHODS));
    }   

跟踪源码得到结论,spy和mock方法最大的区别是配置不同的Mock对象MockSetting。使其行为不一样。

Stub

  @Test
    public void stubtest() {
        ArrayList a=new ArrayList();
        List mock=spy(a);
        //List mock=mock(ArrayList.class);
        //这里如果是 spy的类型 会执行真实方法 add("a")
        when(mock.add("a")).thenReturn(false);
        doThrow(new RuntimeException()).when(mock).add("b");
        doReturn(false).when(mock).add("c");
        doAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return false;
            }
        }).when(mock).add("d");
        //doCallRealMethod不能定义抽象方法,如是通过mock创建需要配置构造对象
        //OtherAbstract spy = mock(OtherAbstract.class, withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS));
        doCallRealMethod().when(mock).add(0,"e");
        //doNothing只能定义void方法
        doNothing().when(mock).clear();
        System.out.println(mock.add("a"));
        System.out.println(mock.add("c"));
        System.out.println(mock.add("d"));
        mock.add(0,"e");
        mock.clear();
        System.out.println(mock.size());
        System.out.println(mock.add("b"));
    }

可通过when|doThrow|doReturn|doAnswer|doCallRealMethod|doNothing定义stub行为,注意spy与class mock使用是的区别。

Argument Matcher

    @Test
    public void argTest() {
        List mock = mock(List.class);
        
        //通过Argument Matcher anytring()定义参数,提供有anyList,anyBoolean等等比较多不一一列举
        when(mock.add(anyString())).thenReturn(false);
        System.out.println(mock.add("a"));
        System.out.println(mock.add("b"));
        List list = new ArrayList();
        List spy = spy(list);
        //支持lambda
        when(spy.add(argThat((String e) -> e.length() < 3))).thenReturn(false);

        System.out.println(mock.add("a"));
        System.out.println(mock.add("b"));
        System.out.println(spy.add("b"));
        System.out.println(spy.add("b22"));

    }

Argument Matcher 用于定义stubing传入的参数,默认封装了anyString()等常用的测试参数,可以自定义创建需要的测试的参数范围。

Verify

//verify(mock).someMethod() 相当于 verify(mock, times(1)) 
    @Test
    public void argVerify() {
        List mock = mock(List.class);
        when(mock.add(anyString())).thenReturn(false);
        System.out.println(mock.add("a"));
        System.out.println(mock.add("b"));
        List list = new ArrayList();
        List spy = spy(list);
        when(spy.add(argThat((String e) -> e.length() < 3))).thenReturn(false);

        System.out.println(mock.add("a"));
        System.out.println(mock.add("b"));
        System.out.println(spy.add("b"));
        System.out.println(spy.add("b22"));
        // times校验行为调用次数,上面代码块中mock.add("a")执行了两次,如果校验times(1),则不通过
        //times提供了多个方法支持atLeastOnce()等
        verify(mock,times(2)).add("a");
        verify(mock,times(2)).add("b");
        verify(spy).add("b");
        verify(spy).add("b22");
    }

用于校验mock对象是否执行了你想要的行为

上一篇 下一篇

猜你喜欢

热点阅读