mockito使用教程 verify校验 assert断言 when thenReturn使用 解决mock静态方法报错 笔记

本文介绍了Mockito的三种实现方式,包括@RunWith注解、@Before与Mockito.mock结合及@Rule的使用。详细讲解了@ InjectMocks和@Mock的关系,verify方法的校验调用次数、参数捕获和调用顺序验证。此外,讨论了如何使用when()来控制返回值和异常,并指出Mockito默认不支持静态方法,推荐使用Powermock进行补充,提供相应依赖配置和使用示例。

Mockito 三种实现

1.@RunWith()+@Mock注解实现

@RunWith(MockitoJUnitRunner.class)
public class AccountServiceRunwithTest {
    @Mock
    private AccountService accountService;

2. @Befor+Mockito.mock

private AccountService accountService;

    private List<Integer> mockList;

    @Before
    public void before() {
        accountService = mock(AccountService.class);
        mockList = mock(List.class);
    }

3.@RunWith + @Rule

@RunWith(JUnit4.class)
public class AccountServiceRulesTest {

    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule();

@InjectMocks和@Mock的关系

@InjectMocks:创建类的一个实例,这个实例就是需要测试的实例
    
@Mock:创建的模拟,模拟的东西会注入到创建的实例类中

verify的重要用法

校验是否调用或调用了几次

verify(mockedList, atLeastOnce()).add("one");
verify(mockedList, times(1)).add("two");
verify(mockedList, times(3)).add("three times");
verify(mockedList, never()).isEmpty();
第一句校验 mockedList.add("one") 至少被调用了 1(atLeastOnce)
第二句校验 mockedList.add("two") 被调用了 1(times(1))
第三句校验 mockedList.add("three times") 被调用了 3(times(3))
第四句校验 mockedList.isEmpty() 从未被调用(never)

参数捕获

verify(mockList).add("1");
当我们验证这个mock的方法add("1")是否被调用,如果被调用则通过测试,否则抛出异常

验证调用顺序

我们可以使用InOrder来验证调用顺序。我们可以跳过任何方法进行验证,但是要验证的方法必须以相同的顺序调用。
InOrder inOrder = inOrder(mockList, mockMap);
inOrder.verify(mockList).add("carpe");
inOrder.verify(mockList, calls(1)).size();
inOrder.verify(mockList).isEmpty();
inOrder.verify(mockMap).isEmpty();

断言Assert

  1)assertEquals()方法
  判断两个对象是否相等,并返回booleanint等类型,前为期望值,后为输入值。
   assertEquals(返回值,Object expected,Object actual);
 
  2)assertTrue()/assertFalse()
   判断测试的对错,condition是期望,message是实际值。
   assertTrue(condition,message);
   或assertFalse(condition,message);
  
  3)assertArrayEquals()
  判断两个数组是否相等
  assertArrayEquals(a[],b[]);

关于when

when(…).thenReturn(…) 可以用于控制返回值



Random mockRandom = mock(Random.class);

when(mockRandom.nextInt()).thenReturn(1);

Assert.assertEquals(1, mockRandom.nextInt());

when(…).thenThrow(…) 可以用于控制返回异常

   @Test
    public void test() {

        Random mockRandom = mock(Random.class);

        when(mockRandom.nextInt()).thenThrow(new RuntimeException("异常"));

        try {
            mockRandom.nextInt();
            Assert.fail();  // 上面会抛出异常,所以不会走到这里
        } catch (Exception ex) {
            Assert.assertTrue(ex instanceof RuntimeException);
            Assert.assertEquals("异常", ex.getMessage());
        }

    }

ps :thenReturn和thenThrow都可以返回多个值/异常,请自行补充

当测试void返回类型得方法时 , 就需要用 doThrow来抛出异常


doThrow(new RuntimeException("异常")).when(Service).voidMethod();

Mockito 默认是不支持静态方法

比如我们在 ExampleService 类中定义静态方法 add:

public class ExampleService {

        public static int add(int a, int b) {
            return a+b;
        }

    }

尝试给静态方法打桩,会报错:

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

import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class MockitoDemo {

    @Test
    public void test() {

        // 会报错
        when(ExampleService.add(1, 2)).thenReturn(100);

    }

}

可以用 Powermock 弥补 Mockito 缺失的静态方法 mock 功能

在 build.gradle 中配置以下依赖:

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.25.1'

    // PowerMock 相关依赖
    testCompile group: 'org.powermock', name: 'powermock-core', version: '2.0.0'
    testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0'
    testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0'
}

示例:

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Mockito.*;

@RunWith(PowerMockRunner.class)     // 这是必须的
@PrepareForTest(ExampleService.class)  // 声明要处理 ExampleService
public class MockitoDemo {
    @Test
    public void test() {

        PowerMockito.mockStatic(ExampleService.class);  // 这也是必须的

        when(ExampleService.add(1, 2)).thenReturn(100);

        Assert.assertEquals(100, ExampleService.add(1, 2));
        Assert.assertEquals(0, ExampleService.add(2, 2));

    }
}

PowerMockRunner 支持 Mockito 的 @Mock 等注解

上面我们用了 PowerMockRunner ,MockitoJUnitRunner 就不能用了。但不要担心, @Mock 等注解还能用。

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.Random;

import static org.mockito.Mockito.*;

@RunWith(PowerMockRunner.class)
public class MockitoDemo {

    @Mock
    private Random random;

    @Test
    public void test() {

        when(random.nextInt()).thenReturn(1);
        Assert.assertEquals(1,  random.nextInt());

    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值