如何使用Mockito框架为Java服务编写when...thenReturn模式的Mock测试
调整思路与实现方案
第一步:修改业务代码适配Mock逻辑
你当前CodeConfigBuilder直接通过@Value读取配置,没有依赖你定义的PropertySourceResolver,导致Mock的配置类无法注入生效,先调整依赖关系:
@Component public class CodeConfigBuilder { // 移除@Value注入的字段,改为依赖配置读取类 private final PropertySourceResolver propertySourceResolver; // 构造器注入,Mockito可以通过构造器自动注入Mock对象 public CodeConfigBuilder(PropertySourceResolver propertySourceResolver) { this.propertySourceResolver = propertySourceResolver; } public void validateRequestAndSetDefaults(PromoRequest promoRequest) { prefixAndPostFixControlAccordingToLength(promoRequest); } private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest) { if (promoRequest.getPostfix() != null) { // 从配置类读取前缀长度 int lengthControl = propertySourceResolver.getPrefixLength() + promoRequest.getPostfix().length(); if (lengthControl >= promoRequest.getLength()) { throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT); } } } }
第二步:重写测试类,使用when...thenReturn打桩
你之前的测试类注解、依赖注入逻辑都存在错误,调整后代码如下:
@RunWith(MockitoJUnitRunner.class) class CodeConfigBuilderTest { // 纯Mockito单元测试用@Mock即可,@MockBean是SpringBoot测试注解 @Mock private PropertySourceResolver propertySourceResolver; // @InjectMocks标注在要测试的目标类上,会自动将@Mock的对象注入进去 @InjectMocks private CodeConfigBuilder codeConfigBuilder; private PromoRequest promoRequest; @Before public void init() { promoRequest = new PromoRequest(); promoRequest.setPrefix("ABC"); promoRequest.setPostfix("ABCDABCD"); // 后缀长度为8 promoRequest.setQuantity(10); promoRequest.setLength(12); promoRequest.setCharset("ABCDEF"); } // 测试正常场景:前缀+后缀长度小于总长度,验证不抛异常 @Test public void validateRequest_shouldSuccess_whenSumLengthValid() { // 打桩:指定调用getPrefixLength时返回3 when(propertySourceResolver.getPrefixLength()).thenReturn(3); // 执行待测方法 3+8=11 <12 符合规则 codeConfigBuilder.validateRequestAndSetDefaults(promoRequest); } // 测试异常场景:前缀+后缀长度大于等于总长度,验证抛出预期异常 @Test(expected = BadRequestException.class) public void validateRequest_shouldThrowException_whenSumLengthInvalid() { // 打桩:指定调用getPrefixLength时返回4,4+8=12 >=12 触发异常 when(propertySourceResolver.getPrefixLength()).thenReturn(4); codeConfigBuilder.validateRequestAndSetDefaults(promoRequest); } }
核心逻辑说明
- 所有外部依赖(配置读取、第三方调用等)都抽成可注入的Bean,才能通过Mockito模拟返回值,不需要加载Spring上下文和真实配置文件,测试用例更稳定
when...thenReturn的作用是自定义Mock对象的方法返回值,可灵活调整返回值覆盖所有正常、边界、异常场景,不需要修改配置文件就能完成全场景测试
内容的提问来源于stack exchange,提问作者mark whalf
相关产品推荐
相关产品推荐

