单元测试:参数匹配器和参数捕捉器

第一章、参数匹配器

1.1)参数匹配器列表

Mockito框架中的参数匹配器是用于在测试中进行灵活验证和存根设置的工具。如果使用了参数匹配器,方法中的所有参数都必须是匹配器。

verify(mockClass).someMethod(anyInt(), anyString(), eq("third argument"));

参数匹配器列表:

参数匹配器解释说明
any()参数为任意类型
anyXxx()包括anyInt、anyBoolean、anyByte、anyChar、anyFloat、Double、anyString、anyList、anyIterable等等
any(Class<T> type)任意指定的Class类型,除了null
isA(Class<T> type)指定类型的实现对象
eq(value)参数匹配指定的值
same(expectedObject)参数和给定的值是同一个对象
isNull()参数是null值
notNull()参数非null
nullable(Class clazz)null 或者给定的类型
contains(String substring)参数包含指定的字符串
matches(String regex)匹配正则表达式
endsWith(String suffix)以xx结尾
startsWith(String prefix)以xx开头
argThat(ArgumentMatcher matcher)自定义匹配器
times()匹配精确的次数

1.2)参数匹配器示例

①anyInt()

示例:使用anyInt()方法来指定参数的范围,从而实现了对mockList.get()方法的灵活验证和存根设置。

import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
import org.junit.Test;
import java.util.List;

public class TestList {
    @Test
    public void testList_Argument_Matchers() {
        List<String> mockList = mock(List.class);
        when(mockList.get(anyInt())).thenReturn("Mockito");
        assertEquals("Mockito", mockList.get(0));
        assertEquals("Mockito", mockList.get(1));
        assertEquals("Mockito", mockList.get(2));
    }
}
②any(Class<> type)

示例:使用参数匹配器any(Class type)来存根方法

import static org.mockito.Mockito.*;

public class Example {
    public void testMethod() {
        // 创建一个mock对象
        MyClass myClass = mock(MyClass.class);
        
        // 使用参数匹配器any(Class<T> type)来存根方法
        when(myClass.method(any(String.class))).thenReturn("mocked");

        // 调用被存根的方法
        String result = myClass.method("input");

        // 验证方法是否按预期调用
        verify(myClass).method(any(String.class));
    }
}
③eq()

示例:使用参数匹配器eq(value)来存根方法

import static org.mockito.Mockito.*;

public class Example {
    public void testMethod() {
        // 创建一个mock对象
        MyClass myClass = mock(MyClass.class);
        
        // 使用参数匹配器eq(value)来存根方法
        when(myClass.method(eq("input"))).thenReturn("mocked");

        // 调用被存根的方法
        String result = myClass.method("input");

        // 验证方法是否按预期调用
        verify(myClass).method(eq("input"));
    }
}
④same(expectedObject)
import org.junit.Test;
import static org.mockito.Mockito.*;

public class ExampleTest {

    @Test
    public void testWithSameMatcher() {
        // 创建mock对象
        MyClass myClass = mock(MyClass.class);

        // 创建预期参数对象
        Object expectedObject = new Object();

        // 设置预期行为,使用参数匹配器same(value)来确保方法调用的参数是同一个对象
        when(myClass.methodWithArgument(same(expectedObject))).thenReturn("mockedResult");

        // 调用被测试方法
        String result = myClass.methodWithArgument(expectedObject);

        // 验证预期行为
        verify(myClass).methodWithArgument(same(expectedObject));
    }
}
⑤endsWith()
import org.junit.jupiter.api.Test;
import static org.mockito.ArgumentMatchers.endsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class ExampleTest {

    @Test
    public void testMethodWithEndsWithMatcher() {
        // 创建mock对象
        MyClass myClass = mock(MyClass.class);

        // 调用被测试方法
        myClass.myMethod("test123");

        // 验证方法是否被调用,并且传入的参数以特定后缀结尾
        verify(myClass).myMethod(endsWith("123"));
    }
}

特殊的匹配器,用于验证实际对存根的调用,例如times()、never()、atLeast()等。

第二章、参数捕捉器

帮助我们捕捉传递给模拟对象方法的参数,并且使我们能够对这些参数进行额外的断言。在Java中,Mockito库提供了@Captor注解和ArgumentCaptor类来实现参数捕捉器的功能。

2.1)@Captor

@Captor是Mockito框架中的一个注解,用于捕获方法调用时传入的参数,以便在测试中对参数进行断言或验证。
参数捕获:在测试中,使用@Captor可以捕获方法调用时传递的参数,以便在后续的断言中验证参数的值。
参数验证:通过捕获参数,可以对传递给方法的参数进行验证,确保方法得到了期望的参数值。
灵活性:@Captor提供了一种灵活的方式来处理方法调用时的参数,使得测试更加精确和可靠。

// 示例代码中使用@Captor注解捕获参数
@ExtendWith(MockitoExtension.class)
class ExampleTest {

    @Captor
    //@Captor注解创建了一个ArgumentCaptor对象
    private ArgumentCaptor<String> stringCaptor;

    @Mock
    private SomeClass someClass;

    @Test
    void testSomething() {
        // 调用被测试方法
        someClass.doSomething("test");

        //verify(someClass)验证someClass对象的doSomething方法是否被调用
 //通过stringCaptor.capture()捕获doSomething方法的参数
        verify(someClass).doSomething(stringCaptor.capture());
        //通过stringCaptor.getValue()获取捕获的参数值
        assertEquals("test", stringCaptor.getValue());
    }
}

2.2)ArgumentCaptor类

ArgumentCaptor argument = ArgumentCaptor.forClass(Class clazz) 创建指定类型的参数捕获器

argument.getValue() 获取方法参数值,如果方法进行了多次调用,它将返回最后一个参数值

argument.getAllValues() 方法进行多次调用后,返回多个参数值

@Test
public void argumentCaptor() {
    // 创建模拟对象
    List mockList = mock(List.class);
    List mockList1 = mock(List.class);

    // 在模拟对象上调用add方法
    mockList.add("666");
    mockList1.add("aaa");
    mockList1.add("ttt");

    // 获取方法参数
    ArgumentCaptor argument = ArgumentCaptor.forClass(String.class);
    verify(mockList).add(argument.capture());
    System.out.println(argument.getValue());    //666
    // 输出捕获的参数值,预期为"666"

    // 多次调用获取最后一次
    ArgumentCaptor argument1 = ArgumentCaptor.forClass(String.class);
    verify(mockList1, times(2)).add(argument1.capture());
    System.out.println(argument1.getValue());    //ttt
    // 输出捕获的参数值,预期为"ttt"

    // 获取所有调用参数
    System.out.println(argument1.getAllValues());    //[aaa, ttt]
    // 输出捕获的所有参数值,预期为["aaa", "ttt"]
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值