Java调用AWS Lambda方法单元测试Mock LambdaClient不生效问题求助
问题原因
你遇到的Mock不生效的核心是依赖没有注入到测试目标类中,具体问题点如下:
RoutingService的无参构造函数内部自行初始化了真实的LambdaClient实例,你在测试类中通过@Mock生成的Mock对象完全没有被RoutingService使用,自然不会拦截真实调用- 你构造的
fakeResponse是空实例,即使Mock生效,调用result.payload().asUtf8String()也会抛出空指针异常 - 业务代码中存在多处拼写错误,会导致编译/运行异常:比如
SDKBytes应为SdkBytes、routingURI后续使用时写成了routingUri、AWSServiceExceptuion拼写错误、方法最后返回的response变量未定义
修复方案
第一步:改造RoutingService支持依赖注入
新增构造函数,允许外部传入LambdaClient、环境、区域参数,原有生产逻辑保持不变:
public class RoutingService { private LambdaClient lambdaClient; private String env; private String region; // 新增测试用构造函数 public RoutingService(LambdaClient lambdaClient, String env, String region){ this.lambdaClient = lambdaClient; this.env = env; this.region = region; } // 原有生产用无参构造保持不变 public RoutingService(){ this(LambdaClient.builder().build(), System.getenv(ENVIRONMENT), System.getenv(REGION)); } // 剩余原有代码保持不变,注意修正拼写错误 }
第二步:修改单元测试用例
调整测试代码,将Mock的LambdaClient注入到RoutingService实例中,同时构造合法的返回值:
// 测试类上方新增Mockito扩展注解(JUnit5环境,老版本可以保留initMocks) @ExtendWith(MockitoExtension.class) public class RoutingServiceTest { @Mock private LambdaClient lambdaClient; @Test void invokeLambda() throws IOException, JSONException { // 原有构造fakeRequest的代码保持不变 Map<String,String> queryStringParameters = new HashMap<>(); queryStringParameters.put("test","GOOG"); String[] cookies = {"cookiea", "cookieb"}; Map<String,String> headers = new HashMap<>(); headers.put("header1","valuex"); headers.put("header2","valuey"); InvokeLambda fakeRequest = new InvokeLambda.InvokeLambdaBuilder() .cdnToken("cdn-token").applicationName("eaf-4137-demo") .service("quote").method("GET") .path("QuoteService/getQuote") .queryString(queryStringParameters) .headers(headers) .cookies(cookies) .body("body") .requestId("request-id") .build(); // 构造带合法payload的假返回 RoutingResponse expectedResp = new RoutingResponse(); expectedResp.setStatusCode(200); String respJson = new ObjectMapper().writeValueAsString(expectedResp); InvokeResponse fakeResponse = InvokeResponse.builder() .payload(SdkBytes.fromUtf8String(respJson)) .statusCode(200) .build(); Mockito.when(lambdaClient.invoke(Mockito.any(InvokeRequest.class))).thenReturn(fakeResponse); // 实例化RoutingService时传入Mock的lambdaClient和测试用环境、区域值 RoutingService routingService = new RoutingService(lambdaClient, "test", "us-east-1"); RoutingResponse response = routingService.invokeLambda(fakeRequest); Assertions.assertEquals(200, response.getStatusCode()); } }
内容的提问来源于stack exchange,提问作者Ramakrishna Tolety
相关产品推荐
相关产品推荐

