在AnnotatinConfigApplicationContext中注入模拟Bean失败。

问题描述 投票:0回答:1

我的Springboot应用没有主类,因为它有一个AWS Lambda handler。

这是我的classtobetested的样子。

@Slf4j
@SpringBootApplication
@Configuration
@ComponentScan(basePackages = "${spring.basepackages}")
@EnableAutoConfiguration
public class AWSLambdaHandler implements RequestHandler<LambdaRequest, LambdaResponse> {

    @Override
    public LambdaResponse handleRequest(LambdaRequest input, Context context) {

        GenericResponse serviceResponse = new GenericResponse();
        LambdaResponse lambdaResponse = new LambdaResponse();
        ObjectMapper mapper = new ObjectMapper();

        try {
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
            ServiceClass service = applicationContext.getBean(ServiceClassImpl.class);
            serviceResponse = service.process(input);
            lambdaResponse.setBody(mapper.writeValueAsString(serviceResponse));
        } catch (JsonProcessingException e) {
            log.error("Exception occured in Handler-" + e.getMessage());
            //Setting error codes and messages for the response
        } 
        return lambdaResponse;
    }
}

我的配置类是这样的

@Configuration
@ComponentScan(basePackages = "${spring.basepackages}")
@PropertySource("classpath:application.properties")
@EnableAutoConfiguration
public class Config{
    //No additional code here.
}

我的Testclass是这样的

@SpringBootTest(classes = Config.class)
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
public class LambdaHandlerTest{

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private AWSLambdaHandler handler;

    @MockBean
    private GenericResponse genericResponse;

    @MockBean
    ServiceClass mockService;

    @MockBean
    ServiceImpl mockServiceImpl;

    @MockBean
    Context context;


    @Test
    public void testHandleRequest_success() {
        when(mockService.getOrdersList(any())).thenReturn(genericResponse);
        LambdaResponse response = handler.handleRequest(createRequest(), context);
    }

    private LambdaRequest createRequest() {
        LambdaRequest request = new LambdaRequest();
        request.setCustomerNo(TestUtils.CUSTOMER_NO);
        request.setOpco(TestUtils.OPCO);
        request.setOrderNo(TestUtils.ORDER_NO);
        request.setUomOrderNo(TestUtils.UOM_ORDER_NO);
        return request;
    }
}

在上面的类中,我正在为服务类创建MockBean,并希望当我运行测试用例时,它能被注入,但实际上是为服务类创建了一个真实的对象,所以我的Mock Stubs没有工作,最终我以异常结束。谁能建议一下,可以做些什么。

java spring spring-boot junit spring-test
1个回答
0
投票

你正在努力绕过Spring Boot Spring Cloud Function。

首先,你的函数应该看起来像这样。


@Slf4j
@SpringBootApplication
public class AWSLambdaHandler implements RequestHandler<LambdaRequest, LambdaResponse> {

    private final ServiceClass service;

    public AWSLambdaHandler(ServiceClas service) {
      this.service=service;
    }

    @Override
    public LambdaResponse handleRequest(LambdaRequest input, Context context) {

        GenericResponse serviceResponse = new GenericResponse();
        LambdaResponse lambdaResponse = new LambdaResponse();
        ObjectMapper mapper = new ObjectMapper();

        try {
            serviceResponse = service.process(input);
            lambdaResponse.setBody(mapper.writeValueAsString(serviceResponse));
        } catch (JsonProcessingException e) {
            log.error("Exception occured in Handler-" + e.getMessage());
            //Setting error codes and messages for the response
        } 
        return lambdaResponse;
    }
}

下一步去掉你的 Config 类,因为这并没有增加任何东西(或者至少删除了除了 @Configuration.

然后重写你的测试,因为试图为响应等创建一个mock没有意义,也不需要MockMVC。

@SpringBootTest
@RunWith(SpringRunner.class)
public class LambdaHandlerTest{

    @Autowired
    private AWSLambdaHandler handler;

    @MockBean
    private ServiceClass mockService;

    @MockBean
    private Context context;

    @Test
    public void testHandleRequest_success() {
        when(mockService.getOrdersList(any())).thenReturn(genericResponse);
        LambdaResponse response = handler.handleRequest(createRequest(), context);
    }

    private LambdaRequest createRequest() {
        LambdaRequest request = new LambdaRequest();
        request.setCustomerNo(TestUtils.CUSTOMER_NO);
        request.setOpco(TestUtils.OPCO);
        request.setOrderNo(TestUtils.ORDER_NO);
        request.setUomOrderNo(TestUtils.UOM_ORDER_NO);
        return request;
    }
}

这应该可以像你想要的那样工作。然而,你现在甚至可以写一个简单的单元测试(由于构造函数注入使用的在 AWSLambdaHandler 而你根本不需要Spring。

@RunWith(MockitoJUnitRunner.class)
public class LambdaHandlerTest{

    @InjectMocks
    private AWSLambdaHandler handler;

    @Mock
    private ServiceClass mockService;

    @Mock
    private Context context;

    @Test
    public void testHandleRequest_success() {
        when(mockService.getOrdersList(any())).thenReturn(genericResponse);
        LambdaResponse response = handler.handleRequest(createRequest(), context);
    }

    private LambdaRequest createRequest() {
        LambdaRequest request = new LambdaRequest();
        request.setCustomerNo(TestUtils.CUSTOMER_NO);
        request.setOpco(TestUtils.OPCO);
        request.setOrderNo(TestUtils.ORDER_NO);
        request.setUomOrderNo(TestUtils.UOM_ORDER_NO);
        return request;
    }
}

最后一个将运行得更快,因为它只是一个简单的单元测试,而这个 @SpringBootTest 是更多的集成测试。

© www.soinside.com 2019 - 2024. All rights reserved.