Не удалось вставить фиктивный компонент в AnnotatinConfigApplicationContext - PullRequest
0 голосов
/ 28 апреля 2020

Мое приложение Springboot не имеет основного класса, поскольку имеет AWS Лямбда-обработчик.

Так выглядит мой класс с диабетом.

@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;
    }
}

Мой класс Config выглядит вот так

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

Мой тестовый класс будет выглядеть так

@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 для класса обслуживания и надеюсь, что он будет введен при запуске моего теста случай, но в действительности для класса обслуживания создается реальный объект, поэтому мои заглушки не работают, и в итоге я получаю исключение. Может кто-нибудь подсказать, пожалуйста, что можно сделать.

1 Ответ

0 голосов
/ 28 апреля 2020

Вы пытаетесь много работать с 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.

. Затем перепишите тест как попытку создания макет для ответа и т. д. c. не имеет смысла, и вам не нужен макет MVC.

@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 - это скорее интеграционный тест.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...