如何用Mockito模拟Gateway测试含Lambda Consumer的Interactor类
模拟Gateway指定固定UUID响应的测试方案
要测试这个Interactor类,咱们用Mockito(Java生态最常用的Mock框架)就能轻松搞定,核心思路是模拟Gateway接口,主动触发它的Consumer<UUID>回调,传入你指定的UUID值。下面是具体步骤和代码示例:
步骤1:准备测试依赖
确保你的测试类引入JUnit(以JUnit 5为例)和Mockito的依赖,比如Maven配置:
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
步骤2:编写测试代码
核心逻辑拆解:
- 模拟
Gateway实例 - 拦截
Gateway.process()调用,手动触发传入的Consumer<UUID>,传入预设的固定UUID - 验证
Interactor是否正确将UUID转为字符串,传递给外层的Consumer<String>
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; @ExtendWith(MockitoExtension.class) class InteractorTest { // 模拟Gateway接口实例 @Mock private Gateway mockGateway; // 构建Interactor并注入模拟的Gateway private Interactor interactor = Interactor.builder().gateway(mockGateway).build(); @Test void process_shouldPassSpecifiedUuidAsStringToResponse() { // 1. 定义你想要的固定UUID UUID fixedUuid = UUID.fromString("123e4567-e89b-12d3-a456-426614174000"); // 2. 拦截Gateway的process方法,触发Consumer回调 doAnswer(invocation -> { // 获取方法传入的Consumer<UUID>参数 Consumer<UUID> uuidConsumer = invocation.getArgument(1); // 主动调用accept,传入预设的UUID uuidConsumer.accept(fixedUuid); return null; // 因为process是void方法,返回null即可 }).when(mockGateway).process(any(String.class), any(Consumer.class)); // 3. 用AtomicReference捕获Interactor返回的响应字符串 AtomicReference<String> capturedResponse = new AtomicReference<>(); // 4. 调用Interactor的process方法 interactor.process("test-message", capturedResponse::set); // 5. 验证结果是否符合预期 assert capturedResponse.get().equals(fixedUuid.toString()); } }
关键细节说明
- 为什么用
doAnswer?因为Gateway.process()是void返回值的方法,没法用常规的when(...).thenReturn(),doAnswer允许我们拦截方法调用,手动处理传入的回调参数。 - 用
AtomicReference是因为Java Lambda无法修改外部非final变量,原子类可以安全捕获回调结果。 - 参数匹配器
any(String.class)和any(Consumer.class)表示匹配任意字符串和Consumer,你也可以换成更精准的匹配规则(比如指定特定的message)。
这样就能完全控制Gateway返回的UUID值,精准测试Interactor的逻辑是否正确啦!
内容的提问来源于stack exchange,提问作者Gadi
相关产品推荐
相关产品推荐

