You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito跨测试类使用Mock实例化的最佳实践问询

最佳实践:在多个测试类中复用Mock配置

Great question! Duplicating mock setup code across multiple test classes is a common annoyance—let’s break down a few clean, maintainable ways to avoid repeating yourself.

1. 抽象测试基类(最通用的非Spring方案)

If you’re writing plain unit tests (not using Spring), create an abstract base class that holds your shared mock and its default configuration. All your test classes can then inherit from this base class to get the pre-configured mock for free.

Example (JUnit 5 + Mockito):

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public abstract class BaseTest {
    @Mock
    protected PropertiesLoader propertiesLoader;

    @BeforeEach
    void setupSharedMocks() {
        // 统一配置一次默认行为
        when(propertiesLoader.getKey()).thenReturn("123");
    }
}

然后你的测试类可以简化成这样:

import org.junit.jupiter.api.Test;

public class TestCrypter extends BaseTest {
    @Test
    void firstTest() {
        // propertiesLoader已经预配置完成!
        String key = propertiesLoader.getKey();
        // 在这里编写你的断言逻辑
    }
}

public class TestUserService extends BaseTest {
    @Test
    void firstTest() {
        // 同样的预配置Mock直接可用
        String key = propertiesLoader.getKey();
        // 测试你的用户服务逻辑
    }
}

如果是JUnit 4,只需要把@ExtendWith(MockitoExtension.class)换成@RunWith(MockitoJUnitRunner.class),@BeforeEach换成@Before即可。

2. Spring Boot测试:复用MockBean配置

如果你在使用Spring Boot测试,可以把Mock配置提取到专门的测试配置类中,这样既保持测试类简洁,也符合Spring的依赖注入模式。

Example:

首先创建一个测试配置类:

import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SharedMockConfig {
    @MockBean
    public PropertiesLoader propertiesLoader;

    // Bean创建时初始化Mock行为
    public SharedMockConfig() {
        Mockito.when(propertiesLoader.getKey()).thenReturn("123");
    }
}

然后在你的测试类中导入这个配置:

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;

@SpringBootTest
@Import(SharedMockConfig.class)
public class TestCrypter {
    private final PropertiesLoader propertiesLoader;

    // 通过构造函数注入预配置的Mock
    public TestCrypter(PropertiesLoader propertiesLoader) {
        this.propertiesLoader = propertiesLoader;
    }

    @Test
    void firstTest() {
        String key = propertiesLoader.getKey();
        // 编写测试逻辑
    }
}

// 在TestUserService中同样使用@Import(SharedMockConfig.class)即可

你也可以把@TestConfiguration放在抽象基类中,通过继承的方式复用Spring上下文配置。

3. 自定义Mock Answer(全局默认行为)

如果你希望这个Mock在所有测试中调用getKey()时都返回"123",不需要额外的初始化代码,可以定义一个自定义的Mockito Answer:

import org.mockito.Answer;
import org.mockito.invocation.InvocationOnMock;

// 定义可复用的Answer逻辑
class DefaultKeyAnswer implements Answer<String> {
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable {
        if (invocation.getMethod().getName().equals("getKey")) {
            return "123";
        }
        // 其他方法返回默认Mock值
        return org.mockito.Answers.RETURNS_DEFAULTS.answer(invocation);
    }
}

然后在声明Mock时使用这个自定义Answer:

@Mock(answer = org.mockito.Answers.RETURNS_CUSTOM, customAnswer = DefaultKeyAnswer.class)
private PropertiesLoader propertiesLoader;

这种方式适合有固定全局默认行为的场景,但如果需要在特定测试中覆盖返回值,灵活性会稍差。

怎么选?

  • 普通单元测试选抽象基类:简单直接,集中管理配置。
  • Spring Boot环境选测试配置类:和Spring的依赖注入体系天然适配。
  • 有固定全局默认行为选自定义Answer:一劳永逸,无需额外初始化代码。

内容的提问来源于stack exchange,提问作者Filipe Tabosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:41:33