java单元测试简介(基于SpringBoot)

mockito

通常,在我们写单测时,会遇到被测试类与外部类有依赖的时候,尤其是与数据库相关的这种费时且有状态的类,很难做单元测试。但好在可以通过“Mockito”这种仿真框架来模拟这些比较费时的类,从而专注于测试某个类内部的逻辑。

mock

@Data
public class Cat {
    private String name;

    private long id;

    private int age;

    public void call() {
        System.out.println("miao~");
    }

    public String copy(String str) {
        return str;
    }
}
import static org.mockito.Mockito.*
    @Test
    public void testForMock00() throws Exception {
        // mock对象
        Cat cat = mock(Cat.class);
        // 基本类型返回初始值
        System.out.println(cat.getAge());
        // 包装类型返回null
        System.out.println(cat.getName());
        // 其行为已和原对象脱离
        cat.call();
    }

特点:该对象是一个mock对象,其行为已经和原始对象不同,其public方法返回值已被mock,基本对象返回初始值,包装类型返回null。

创建mock对象的另一种方式:@Mock

    @Mock
    private Cat cat2;

verify

verify方法,可以用来校验mock对象对应的方法是否被调用过,以及具体调用次数

    @Test
    public void testForMock01() throws Exception {
        Cat cat = mock(Cat.class);
        cat.setAge(10);
        // 校验调用了一次setAge,传参10
        verify(cat).setAge(10);
        cat.setAge(9);
        // 校验调用了一次setAge,传参9
        verify(cat, times(1)).setAge(9);
        // 校验调用了两次setAge,传参任意
        verify(cat, times(2)).setAge(anyInt());
    }

stubbing(存根)

当测试的单元依赖这个mock对象的返回值时,我们可以通过提前申明这个函数的返回值来测试各种各样的场景。
提前申明的这个过程被称为存根。

注意点

  • 存根时可以被覆盖的(即对一种情况多次存根的话,以最后一次为准),但是不鼓励这么做,可读性会变差。
  • 一旦存根后,这个函数会一直返回这个值,不管你调用多少次。
        Cat cat = mock(Cat.class);
        // 连续存根 调用getAge 第一次返回1 之后返回2
        when(cat.getAge()).thenReturn(1,2);
        Assert.assertEquals( 1, cat.getAge());
        Assert.assertEquals( 2, cat.getAge());
        Assert.assertEquals( 2, cat.getAge());

        // mock 调用copy 传参 你好 返回 你好
        when(cat.copy("你好")).thenReturn("你好");
        System.out.println(cat.copy("你好"));
        when(cat.copy("包子")).thenReturn("包子");
        // 传参饺子,不符合要求,返回null
        System.out.println(cat.copy("饺子"));

        //传参任意参数,返回包子
        when(cat.copy(any())).thenReturn("包子");
        System.out.println(cat.copy("你好"));

存根也可以用来指定抛出异常

        // 调用getAge 抛出异常
        when(cat.getAge()).thenThrow(new UnsupportedOperationException());
        cat.getAge();

存根也可以设置回调函数,在回调函数中,我们可以获取到对应方法调用时的入参,以及返回值

    @Test
    public void testForMock03() throws Exception {
        Cat cat = mock(Cat.class);
       Answer answer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                // 获取调用的方法名:
                System.out.println(invocationOnMock.getMethod().getName());
                // 获取调用的方法入参:
                System.out.println(Arrays.asList(invocationOnMock.getArguments()));
                // 设置调用的方法返回值:
                return "return is me";
            }
        };
       when(cat.copy(anyString())).thenAnswer(answer);
       System.out.println(cat.copy("包饺子"));
    }

其他指定行为的:
doNothing() 啥也不干
doCallRealMethod() 调用真正的方法(不代理)

Spy(间谍)

对该对象所有方法的调用都直接调用真实方法,但也可以对某些我们关注的方法进行存根

    @Test
    public void testForMock04() throws Exception {
        Cat cat = new Cat();
        cat.setName("喵喵");
        Cat spy = spy(cat);
        when(spy.getName()).thenReturn("包子");
        // 原始对象,真实调用
        System.out.println(cat.getName());
        // 间谍对象且方法被存根
        System.out.println(spy.getName());
        // 间谍对象且方法没有被存根
        spy.call();
        when(spy.copy(anyString())).thenReturn("***");
        // spy对象实际也会访问原始对象的方法,并非直接mock
        System.out.println(spy.copy("你好"));
    }

mock 静态方法

除了实例方法,mockito还可以mock静态方法,具体使用如下。

    @Test
    public void testForMock05() throws Exception {
        Mockito.mockStatic(Cat.class);
        when(Cat.getType()).thenReturn("Cat");
        System.out.println(Cat.getType());
    }

mockito在springboot mock中的实战

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值