Mockito使用技巧之不同条件返回不同结果

背景

当我们进行单元测试的时候,经常会用到 Mockito 对接口进行打桩测试。

一般我们会想下面这个测试用例一样,对接口同一个类型的参数进行Mock返回结果。

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

public class Test {

    @Test
    public void test() {
        
        // mock一个对象
        String s = Mockito.mock(String.class);
        // 打桩 对方法传入任何对应类型的参数,都返回指定的值
        Mockito.when(s.equals(Mockito.any(String.class))).thenReturn(true);
        
        // 当然也可以这样,返回多次不同的结果,但是结果顺序要和测试情况一一对应
        Mockito.when(s.compareTo(Mockito.any(String.class))).thenReturn(-1, 0, 1);
    }
}


这样子虽然能满足大部分情况,但是某些特定情况需要根据不同条件返回不同结果,而且Mockito.when中传入固定值的话又会报错,那我们应该怎么做呢?

解决

我们可以用 Java 的 Predicate 接口来实现。

Maven依赖如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>test-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test-demo</name>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.4.2</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring-boot.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
	

Java 测试代码如下:

package com.test.demo;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;

public class Test {
    
    @Test
    public void test() {
       
        String s = Mockito.mock(String.class);

        // 注意:这儿是接口对应入参的信息
        // null 入参对应情况
        Predicate<String> predicateNull = new Predicate<String>() {
            @Override
            public boolean test(String string) {
                return string == null;
            }
        };

        Mockito.when(s.equals(predicateNull)).thenReturn(true);

        // a 入参对应情况
        Predicate<String> predicateA = new Predicate<String>() {
            @Override
            public boolean test(String string) {
                if ("a".equals(string)) {
                    return true;
                }
                return false;
            }
        };

        Mockito.when(s.equals(predicateA)).thenReturn(false);

        // b 入参对应情况
        Predicate<String> predicateB = new Predicate<String>() {
            @Override
            public boolean test(String string) {
                if ("b".equals(string)) {
                    return true;
                }
                return false;
            }
        };
        
        Mockito.when(s.equals(predicateB)).thenReturn(true);

    }
    
    
    /**
     * 参数匹配器
     * @param argument
     * @return
     * @param <T>
     */
    public <T> T argumentMatcher (Predicate<T> argument) {
        return Mockito.argThat(new ArgumentMatcher<T>() {
            @Override
            public boolean matches(T object) {
                // 这里面也可以自定义一些其他判定条件, 比如判空或者其他
                
                return argument.test(object);
            }
        });
    }
}
posted @ 2025-03-06 22:17  神奇小宝  阅读(340)  评论(0)    收藏  举报