天天看点

单元测试框架——Mockito之Argument Matcher

书接上回:

https://blog.csdn.net/qq_36110736/article/details/107992761

Argument Matcher

Mockito通过equals()方法,来对方法参数进行验证。但有时我们需要更加灵活的参数需求,比如,匹配任何的String类型的参数等等。参数匹配器就是一个能够满足这些需求的工具。

关键方法:

  • IsA()
  • any()
package com.example.demo.matchers;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

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

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

@RunWith(MockitoJUnitRunner.class)
public class ArgumentMatchersTest {

    @Test
    public void testBasic(){
        List<Integer> list = mock(List.class);
        when(list.get(0)).thenReturn(1);
        assertThat(list.get(0),equalTo(1));
        assertThat(list.get(1),nullValue());
    }

    @Test
    public void testComplex(){
        Foo foo = mock(Foo.class);
        when(foo.function(Mockito.isA(Parent.class))).thenReturn(100);
        assertThat(foo.function(new Child1()),equalTo(100));

        reset(foo);

        when(foo.function(Mockito.any(Child1.class))).thenReturn(100);
        assertThat(foo.function(new Child2()),equalTo(100));

    }

    static class Foo{
        int function(Parent p){
            return p.work();
        }
    }

    interface Parent{
        int work();
    }

    class Child1 implements Parent{
        @Override
        public int work() {
            throw new RuntimeException();
        }
    }

    class Child2 implements Parent{
        @Override
        public int work() {
            throw new RuntimeException();
        }
    }
}
           

Wildcard Argument Matcher

Mockito框架中的Matchers类内建了很多参数匹配器,而我们常用的Mockito对象便是继承自Matchers。这些内建的参数匹配器如,anyInt()匹配任何int类型参数,anyString()匹配任何字符串,anySet()匹配任何Set等。下面通过例子来说明如何使用内建的参数匹配器:

添加被测试类:

package com.example.demo.service;

import java.io.Serializable;
import java.util.Collection;

public class MatcherService {
    public int method1(int i, String s, Collection<?> c, Serializable ser){
        throw new RuntimeException();
    }
    public void method2(int i, String s, Collection<?> c, Serializable ser){
        throw new RuntimeException();
    }
}
           

测试类

package com.example.demo.matchers;

import com.example.demo.service.MatcherService;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

@RunWith(MockitoJUnitRunner.class)
public class WildcardArgumentMatcherTest {

    @Mock
    private MatcherService matcherService;

    @Test
    public void testWildcardMethod1(){
        when(matcherService.method1(anyInt(),anyString(),anyCollection(),isA(Serializable.class))).thenReturn(100);
        int ressult = matcherService.method1(1,"test", Collections.emptyList(),"");
        assertThat(100,equalTo(ressult));
    }

    @Test
    public void testWilcardSpcMethod1(){
        when(matcherService.method1(anyInt(),eq("test"),anyCollection(),isA(Serializable.class))).thenReturn(100);
        when(matcherService.method1(anyInt(),eq("wang"),anyCollection(),isA(Serializable.class))).thenReturn(200);

        int ressult = matcherService.method1(1,"test", Collections.emptyList(),"");
        assertThat(100,equalTo(ressult));
        ressult = matcherService.method1(1,"wang", Collections.emptyList(),"");
        assertThat(200,equalTo(ressult));
    }

    @Test
    public void testWildcardMethod2(){
        List<Object> list = Collections.emptyList();
        doNothing().when(matcherService).method2(anyInt(),anyString(),anyCollection(),isA(Serializable.class));
        matcherService.method2(1,"test",list,"");
        verify(matcherService,times(1)).method2(1,"test",list,"");

    }
    @After
    public void after(){
        reset(matcherService);
    }
}
           

注意:

如果使用了参数匹配器,那么所有的参数需要由匹配器来提供,否则将会报错。假如我们使用参数匹配器stubbing了mock对象的方法,那么在verify的时候也需要使用它。

参考

https://www.bilibili.com/video/BV1jJ411A7Sv?p=7