Java之Mockito

Mockito资源:

官网: https://site.mockito.org/

API文档:https://static.javadoc.io/org.mockito/mockito-core/2.23.0/overview-summary.html

项目源码:https://github.com/mockito/mockito

Mockito实战:

配置pom.xml

<dependencies>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.23.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Mockito实例一

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Iterator;

import static org.mockito.Mockito.*;

public class OneTest {

    //验证行为
    @Test
    public void verify_behaviour(){
        List mockList = mock(List.class);

        mockList.add(1);
        mockList.clear();

        verify(mockList).add(1);
        verify(mockList).clear();
    }

    //模拟期望的结果
    @Test
    public void when_thenReturn(){
        Iterator mockIterator = mock(Iterator.class);
        //期望当mockIterator调用next()时第一次返回hello,大于一次后返回world
        when(mockIterator.next()).thenReturn("hello").thenReturn("world");
        
        String result = mockIterator.next() + " " + mockIterator.next() + " " + mockIterator.next();

        Assert.assertEquals("hello world world", result);
    }
    
    @Test(expected = IOException.class)
    public void when_thenThrow() throws IOException{
        OutputStream mockOutputStream = mock(OutputStream.class);
        OutputStreamWriter writer = new OutputStreamWriter(mockOutputStream);
        //期望当流关闭时抛出异常
        doThrow(new IOException()).when(mockOutputStream).close();
        mockOutputStream.close();
    }
    
    //RETURNS_SMART_NULLS参数
    @Test
    public void returnsSmartNullsTest(){
        List mocklist = mock(List.class, RETURNS_SMART_NULLS);
        System.out.println(mocklist.get(0));
        System.out.println(mocklist.toArray().length);
    }
    
}

Mockito实例二

RailwayTicket.class

public class RailwayTicket {
    private String destination;

    public String getDestination(){
        return destination;
    }

    public void setDestination(){
        this.destination = destination;
    }
}

Account.class

public class Account {
    private RailwayTicket railwayTicket;

    public RailwayTicket getRailwayTicket(){
        return railwayTicket;
    }

    public void setRailwayTicket(){
        this.railwayTicket = railwayTicket;
    }
}

测试代码:

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.Mockito.*;

public class OneTest {

    //RETURNS_DEEP_STUBS参数
    @Test
    public void deepstubsTest(){
        Account account = mock(Account.class, RETURNS_DEEP_STUBS);
        when(account.getRailwayTicket().getDestination()).thenReturn("BeiJing");

        account.getRailwayTicket().getDestination();
        verify(account.getRailwayTicket()).getDestination();
        Assert.assertEquals("BeiJing", account.getRailwayTicket().getDestination());
    }

}

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.Mockito.*;

public class OneTest {

    //RETURNS_DEEP_STUBS参数
    @Test
    public void deepstubsTest(){
        Account account = mock(Account.class, RETURNS_DEEP_STUBS);
        RailwayTicket railwayTicket = mock(RailwayTicket.class);
        when(account.getRailwayTicket()).thenReturn(railwayTicket);
        when(railwayTicket.getDestination()).thenReturn("BeiJing");

        account.getRailwayTicket().getDestination();
        verify(account.getRailwayTicket()).getDestination();
        Assert.assertEquals("BeiJing", account.getRailwayTicket().getDestination());
    }

}

Mockito实例三

测试代码:

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class OneTest {

    //使用注解来模拟
    @Mock
    private List mockList;

    //初始化mock
    public OneTest(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void verify_behaviour(){
        mockList.add(1);
        verify(mockList).add(1);
    }

}

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class OneTest {

    //使用注解来模拟
    @Mock
    private List mockList;

    @Test
    public void verify_behaviour(){
        mockList.add(1);
        verify(mockList).add(1);
    }

}

Mockito实例四

测试代码:

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.Mockito.*;

public class OneTest {

    //参数匹配
    @Test
    public void with_arguments(){
        Comparable comparable = mock(Comparable.class);

        when(comparable.compareTo("Test")).thenReturn(1);
        when(comparable.compareTo("Omg")).thenReturn(2);
        Assert.assertEquals(1, comparable.compareTo("Test"));
        Assert.assertEquals(2, comparable.compareTo("Omg"));
        //默认值
        Assert.assertEquals(0, comparable.compareTo("Not stub"));
    }

}

Mockito实例五

Person.class

class Person{
    private int id;
    private String name;

    Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

PersonDao.class

public interface PersonDao {
    Person getPerson(int id);

    boolean update(Person person);
}

PersonService.class

public class PersonService {
    private PersonDao personDao;

    PersonService(PersonDao personDao) {
        this.personDao = personDao;
    }

    public void update(int id,String name){
        personDao.update(new Person(id,name));
    }
}

测试代码:

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.Mockito.*;
import org.mockito.ArgumentCaptor;

public class OneTest {

    //捕获参数来断言
    @Test
    public void capturing_args(){
        PersonDao personDao = mock(PersonDao.class);
        PersonService personService = new PersonService(personDao);

        ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
        personService.update(1,"jack");
        
        verify(personDao).update(argument.capture());
        Assert.assertEquals(1,argument.getValue().getId());
        Assert.assertEquals("jack",argument.getValue().getName());
    }
}

Mockito实例六

CustomAnswer.class

import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class CustomAnswer implements Answer<String> {

    //使用Answer生成我们期望的值
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable{
        Object[] args = invocation.getArguments();
        return "Hello World:" + args[0];
    }
}

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    //Answer结构
    @Test
    public void answer_callback(){
        List mockList = mock(List.class);
        when(mockList.get(anyInt())).thenAnswer(new CustomAnswer());
        Assert.assertEquals("Hello World:0", mockList.get(0));
        Assert.assertEquals("Hello World:99", mockList.get(99));
    }
}

import org.junit.Assert;
import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class OneTest {

    //Answer结构
    @Test
    public void answer_callback(){
        List mockList = mock(List.class);
        使用Answer生成我们期望的值
        when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {
            @Override
            public String answer(InvocationOnMock invocation) throws Throwable{
                Object[] args = invocation.getArguments();
                return "Hello World:" + args[0];
            }
        });
        Assert.assertEquals("Hello World:0", mockList.get(0));
        Assert.assertEquals("Hello World:99", mockList.get(99));
    }
}

Mockito实例七

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class OneTest {

    //使用Answer来对未预设的方法设置默认期望值
    @Test
    public void unstubbed_invocations(){
        List mockList = mock(List.class, new Answer() {
            @Override
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                return 99;
            }
        });

        Assert.assertEquals(99, mockList.get(1));
        Assert.assertEquals(99, mockList.size());
    }
}

Mockito实例八

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.LinkedList;
import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    //用spy监控真实对象
    @Test(expected = IndexOutOfBoundsException.class)
    public void spy_on_real_objects(){
        List list = new LinkedList();
        List spy = spy(list);

        //下面预设的spy.get(0)会报错,因为会调用真实对象的get(0),所以会抛出越界异常
        //when(spy.get(0)).thenReturn(1);

        //使用doReturn-when可以避免when-thenReturn调用真实对象api
        doReturn(99).when(spy).get(99);
        when(spy.size()).thenReturn(100);

        spy.add(1);
        spy.add(2);

        verify(spy).add(1);
        verify(spy).add(2);

        Assert.assertEquals(100,spy.size());
        Assert.assertEquals(1,spy.get(0));
        Assert.assertEquals(2,spy.get(1));
        Assert.assertEquals(999,spy.get(999));
        spy.get(2);
    }

}

Mockito实例九

A.class

public class A {
    public int doSomething(int i){
        return i;
    }
}

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    @Test
    public void real_partial_mock(){
        List spyList = spy(new ArrayList());
        Assert.assertEquals(0, spyList.size());

        A a = mock(A.class);
        when(a.doSomething(anyInt())).thenCallRealMethod();
        Assert.assertEquals(99, a.doSomething(99));
    }

}

Mockito实例十

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    @Test
    public void reset_mock(){
        List mockList = mock(List.class);
        when(mockList.size()).thenReturn(10);
        mockList.add(1);
        Assert.assertEquals(10, mockList.size());
        //清除所有预设
        reset(mockList);
        Assert.assertEquals(0, mockList.size());

    }

}

Mockito实例十一

测试代码:

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    //验证调用次数
    @Test
    public void verifying_number_of_invocations(){
        List mockList = mock(List.class);
        mockList.add(1);
        mockList.add(2);
        mockList.add(2);
        mockList.add(3);
        mockList.add(3);
        mockList.add(3);

        //验证add(1)是否被调用1次
        verify(mockList, times(1)).add(1);
        //验证add(2)是否被调用2次
        verify(mockList, times(2)).add(2);
        //验证add(3)是否被调用3次
        verify(mockList, times(3)).add(3);
        //验证add(4)是否从未被调用
        verify(mockList, never()).add(4);
        //验证add(1)至少被调用1次
        verify(mockList, atLeastOnce()).add(1);
        //验证add(2)至少被调用2次
        verify(mockList, atLeast(2)).add(2);
        //验证add(3)最多被调用3次
        verify(mockList, atMost(3)).add(3);
    }

}

Mockito实例十二

测试代码:

import org.junit.Assert;
import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    //连续调用
    @Test(expected = RuntimeException.class)
    public void consecutive_calls(){
        List mockList = mock(List.class);

        //连续调用时,如果分开,则只有最后一个有效
        when(mockList.get(0)).thenReturn(0);
        when(mockList.get(0)).thenReturn(1);
        when(mockList.get(0)).thenReturn(2);
        when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException());

        Assert.assertEquals(2, mockList.get(0));
        Assert.assertEquals(2, mockList.get(0));
        Assert.assertEquals(0, mockList.get(1));
        Assert.assertEquals(1, mockList.get(1));
        //第三次以上调用都会抛出异常
        mockList.get(1);
    }

}

Mockito实例十三

测试代码:

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;
import org.mockito.InOrder;

public class OneTest {

    //验证执行顺序
    @Test
    public void verification_in_order(){
        List mockList = mock(List.class);
        List mockList2 = mock(List.class);
        mockList.add(1);
        mockList2.add("Hello");

        mockList.add(2);
        mockList2.add("World");

        InOrder inOrder = inOrder(mockList, mockList2);
        inOrder.verify(mockList).add(1);
        inOrder.verify(mockList2).add("Hello");
        inOrder.verify(mockList).add(2);
        inOrder.verify(mockList2).add("World");
    }

}

Mockito实例十四

测试代码:

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;

public class OneTest {

    //验证mock对象无互动发生
    @Test
    public void verify_interaction(){
        List mockList = mock(List.class);
        List mockList2 = mock(List.class);
        List mockList3 = mock(List.class);

        mockList.add(1);
        verify(mockList).add(1);
        verify(mockList, never()).add(2);
        verifyZeroInteractions(mockList, mockList2, mockList3);
    }

}

Mockito实例十五

测试代码:

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.*;
import org.mockito.exceptions.verification.NoInteractionsWanted;

public class OneTest {

    //找出冗余的互动
    @Test(expected = NoInteractionsWanted.class)
    public void find_redundant_interaction(){
        List mockList = mock(List.class);
        mockList.add(1);
        mockList.add(2);
        verify(mockList, times(2)).add(anyInt());
        verifyNoMoreInteractions(mockList);

        List mockList2 = mock(List.class);
        mockList2.add(1);
        mockList2.add(2);
        verify(mockList2).add(1);
        //因为add(2)没有被验证,所以下面的代码会抛出异常
        verifyNoMoreInteractions(mockList2);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值