mock测试样例

package com.wasu.mams.core.service.service.wimpl;

import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*;

/**
 * 本文例子参考:https://wenku.baidu.com/view/8def451a227916888486d73f.html
 */
public class SimpleTest {
    @Test
    public void simpleTest(){
        //创建mock对象,参数可以是类,也可以是接口
        List<String> list = mock(List.class);
        //设置方法的预期返回值
        // when(mock.someMethod).thenReturn("value");
        // 对于static final 修饰的方法不能执行when-thenReturn 方法
        when(list.get(0)).thenReturn("helloworld");
        when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));
        String result = list.get(0);
        // mock对象一旦建立就会自动记录自己的交互行为,所以我们可以有选择的对它的交互行为进行验证
        //验证方法调用(是否调用了get(0))
        verify(list).get(0);
        //junit测试
        assertEquals("helloworld", result);

        Iterator i = mock(Iterator.class);
        /** 下面三种写法是一样的,都是第一次调用返回hello,第二次调用返回world  **/
        // 第一种写法
        when(i.next()).thenReturn("hello").thenReturn("world");
        // 第二种写法
        when(i.next()).thenReturn("hello", "world");
        // 第三种写法
        when(i.next()).thenReturn("hello");
        when(i.next()).thenReturn("world");

        /** ---------------end--------------------- **/
        // doNothing() 模拟不做任何返回(mock对象void方法默认返回)
        doNothing().when(i).remove();
        doThrow(new RuntimeException()).when(i).remove();
        doNothing().doThrow(new RuntimeException()).when(i).remove();
    }

    @Test
    public void argumentMatcherTest(){
        List<String> list = mock(List.class);
        when(list.get(anyInt())).thenReturn("hello","world");
        String result = list.get(0)+list.get(1);
        verify(list, times(2)).get(anyInt());
        assertEquals("helloworld", result);
    }

    /**
     * Mockito框架中的Matchers类内建了很多参数匹配器,而我们常用的Mockito对象就继承于Matchers。
     * 这些内建的参数如anyInt匹配任何int类型的参数,anySet匹配任何set等等。
     */
    @Test
    public void argumentMatcherTest2(){
        Map<Integer,String> map = mock(Map.class);
        when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替换成"hello"就会报错
        map.put(1, "world");
        verify(map).put(eq(1), eq("world")); //eq("world")替换成"world"也会报错
    }

    @Test
    public void verifyInvocate(){

        List<String> mockedList = mock(List.class);
        //using mock
        mockedList.add("once");
        mockedList.add("twice");
        mockedList.add("twice");

        mockedList.add("three times");
        mockedList.add("three times");
        mockedList.add("three times");

        /**
         * 基本的验证方法
         * verify方法验证mock对象是否有没有调用mockedList.add("once")方法
         * 不关心其是否有返回值,如果没有调用测试失败。
         */
        verify(mockedList).add("once");
        // verify(T mock, VerificationMode mode) mode表示调用次数 默认是times(1)
        verify(mockedList, times(1)).add("once");//默认调用一次,times(1)可以省略


        verify(mockedList, times(2)).add("twice");
        verify(mockedList, times(3)).add("three times");

        //never()等同于time(0),一次也没有调用
        verify(mockedList, times(0)).add("never happened");

        //atLeastOnece/atLeast()/atMost() atLeastOnece:至少被调用过一次
        verify(mockedList, atLeastOnce()).add("three times");
        verify(mockedList, atLeast(2)).add("twice");
        // 最多被调用几次
        verify(mockedList, atMost(5)).add("three times");

        // 验证方法能够在指定的100毫秒内执行完成
        verify(mockedList, timeout(100)).add("once");
        // 在超时验证的同时可进行调用次数验证
        verify(mockedList, timeout(100).times(1)).add("twice");
        // 在指定的时间内完成执行次数
        verify(mockedList, timeout(100).times(2)).add("three times");
        // 在指定的时间内至少执行2次
        verify(mockedList, timeout(100).atLeast(2)).add("three times");
    }

    @Test
    public void verifyTest() {
        List<String> mock = mock(List.class);
        List<String> mock2 = mock(List.class);

        when(mock.get(0)).thenReturn("helllo");
        mock.get(0);
        mock.get(1);
        mock.get(2);

        mock2.get(0);

        verify(mock).get(2);
        verify(mock, never()).get(3);
        // 用于验证传入的mock对象是否存在没有验证过的调用方法。建议该方法不要频繁使用
        verifyNoMoreInteractions(mock);
        // 和verifyNoMoreInteractions一样,验证mock2没有验证过任何方法
        verifyZeroInteractions(mock2);
    }

    @Test
    public void inorderTest() {
        List<String> firstMock = mock(List.class);
        List<String> secondMock = mock(List.class);
        firstMock.add("was called first");
        firstMock.add("was called first");
        secondMock.add("was called second");
        secondMock.add("was called third");

        InOrder inOrder = inOrder(firstMock, secondMock);
        // 下面两个验证必须按照上面上面方法执行的顺序验证, 否则报错
        inOrder.verify(firstMock, times(2)).add("was called first");
        inOrder.verify(secondMock).add("was called second");
        // inOrder.verify(secondMock).add("was called third");
        // 只验证创建order时提供的mock对象
        inOrder.verifyNoMoreInteractions();
    }

    @Test
    public void answerTest() {
        List<String> mock3 = mock(List.class);
        // 第一种写法
        when(mock3.get(4)).thenAnswer(new CustomAnswer());
        //  第二种写法
        doAnswer(new CustomAnswer()).when(mock3.get(4));

        //doAnswer(new CustomAnswer()).when(mock3).clear();

        System.out.println(mock3.get(4));
    }

    @Test
    public void argumentCaptorTest() {
        List mock = mock(List.class);
        List mock2 = mock(List.class);
        mock.add("John");
        mock2.add("Brain");
        mock2.add("Jim");

        ArgumentCaptor argument = ArgumentCaptor.forClass(String.class);
        // argument.capture() 捕获方法参数
        // 在verify方法的参数中调用argument.capture()来捕获输入的参数,之后argument变量中就保存了参数值。
        verify(mock).add(argument.capture());
        // argument.getValue() 获取方法参数值,如果方法进行了多次调用,它将返回最后一个参数值
        assertEquals("John", argument.getValue());

       verify(mock2, times(2)).add(argument.capture());
       assertEquals("Jim", argument.getValue());
       // 这里不正确。 argument中存了三个值
       assertArrayEquals(new Object[] {"Brain", "Jim"}, argument.getAllValues().toArray());
    }

    // 当实际返回null可能抛出空指针时返回SmartNulls。String返回"" int返回0等
    @Test
    public void returnsSmartNullsTest() {
        List mock = mock(List.class, RETURNS_SMART_NULLS);
        System.out.println(mock.get(0));
        System.out.println(mock.toArray().length);
    }

    /**
     * spy--对象的监视
     * mock对象只能调用stubbed方法,调用不了真实的方法。但 可以监视一个真实的对象,这时对它进行方法调用时它将调用真实的方法。
     * 注意: 被监视的对象慎用when
     */
    @Test
    public void spyTest() {
        List list = new LinkedList();
        List spy = spy(list);
        // 下面一句会报IndexOutOfBoundsException 因为是调真实对象的方法
        // when(spy.get(0)).thenReturn("foo");
        doReturn(100).when(spy).size();

        spy.add("one");
        spy.add("two");

        System.out.println(spy.get(0));
        System.out.println(spy.size());

        verify(spy).add("one");
        verify(spy).add("two");
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,Mock测试是一种常见的测试方法,用于模拟对象或服务器的行为,以便进行自己想要的测试Mock测试主要有两种场景。 第一种场景是Mock一个对象,通过写入预期的值来进行测试。这种方法主要适用于单元测试,即针对特定语言开发的程序,必须使用基于该语言的Mock方案来实现。例如,Mockito是一种针对Java的Mock框架,适用于单元测试。\[1\] 第二种场景是Mock一个服务器,构造一个虚假的服务来返回预期的结果,以进行测试。这种方法主要适用于接口测试和性能测试Mock方案与程序使用的语言无关,可以使用Java、Python等语言来实现。例如,可以搭建一个Mock服务器来模拟接口的行为,适用范围没有限制。\[2\] 在Java中进行Mock测试时,可以使用一些框架和注解来简化测试代码的编写。例如,使用Mockito框架可以使用注解@RunWith(MockitoJUnitRunner.class)和@Mock来模拟对象的行为,使用@InjectMocks来注入被测试对象。下面是一个示例代码: ```java @RunWith(MockitoJUnitRunner.class) @PrepareForTest(MyService.class) public class UserServiceTest { @InjectMocks private MyService myService; @Mock private MyRepository myRepository; @Mock private YourRepository yourRepository; @Test public void testInjectMocks() { System.out.println(myService.getMyRepository().getClass()); } } ``` 在这个示例中,使用了@RunWith(MockitoJUnitRunner.class)注解来运行测试,并使用@Mock注解来模拟对象的行为。@InjectMocks注解用于注入被测试对象。\[3\] 总结起来,Java中的Mock测试是一种常见的测试方法,可以用于模拟对象或服务器的行为,以进行自己想要的测试。可以使用Mockito等框架和注解来简化测试代码的编写。 #### 引用[.reference_title] - *1* *2* [走进Java接口测试Mock(概念篇)](https://blog.csdn.net/zuozewei/article/details/84892008)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JAVA测试类注解以及Mock测试](https://blog.csdn.net/m0_67793822/article/details/127387243)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值