控制器中的 Springboot Mockito 测试和自动装配 messageSource org.springframework.context.NoSuchMessageException

Springboot Mockito Test and Autowired messageSource in controller org.springframework.context.NoSuchMessageException

我有一个带有 REST 控制器和为其编写的 Mockito 单元测试用例的 Springboot 应用程序。问题是当 运行 测试用例时,我通过读取 RestController 中的 messageSource 得到 NoSuchMessageException。 但是在实际使用 Postman 或其他 Rest 客户端调用它时不会发生。 (我使用 Lombok 来避免样板代码)。

Rest 控制器代码

@RestController
@RequestMapping(value = VERSION + "/product")
@Slf4j
@RequiredArgsConstructor
public class ProductController implements CommonController {

    private final ProductService productService;

    private final MessageSource messageSource;

    
    @PostMapping(path = "")
    public ResponseEntity<CommonResponseDTO> saveProduct(@Valid @RequestBody ProductSaveRequest request) {
        return addNewProduct(request);
    }
    
    private String getMessage(String key) {
        return messageSource.getMessage(key, new Object[0], Locale.getDefault());
    }

}

消息源配置

@Configuration
public class AppConfig {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasenames("classpath:messages/exception-message", "classpath:messages/success-message");
        messageSource.setCacheSeconds(60); //reload messages every 60 seconds
        return messageSource;
    }
}

测试class

@Slf4j
@ExtendWith(SpringExtension.class)
@WebMvcTest(value = ProductController.class)
class ProductControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ProductService productService;

    private static final String PRODUCT_PATH = "/v1/product";
    
@Test
    void saveProduct() throws Exception {

        // productService.add to respond back with mockProduct
        Mockito.doNothing().when(productService).add(Mockito.any(Product.class));

        // Send course as body to /students/Student1/courses
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                .post(PRODUCT_PATH)
                .accept(MediaType.APPLICATION_JSON)
                .content("{\n" +
                        "  \"name\": \"Apple\"\n" +
                        "}")
                .contentType(MediaType.APPLICATION_JSON);

        MvcResult result = mockMvc.perform(requestBuilder).andReturn();

        MockHttpServletResponse response = result.getResponse();

        assertEquals(HttpStatus.CREATED.value(), response.getStatus());
    }
}

异常

org.springframework.context.NoSuchMessageException: No message found under code 'success.confirmation.common.added.code' for locale 'en_US'.

但上述消息存在并成功出现在实际的 REST 客户端中。

项目结构

提前致谢。

@WebMvcTest 注释 loads relevant beans(例如 Filter@ControllerAdviceWebMvcConfigurer)用于测试您的控制器。默认情况下,此 TestContext 不包含任何自定义 @Configuration bean。

您已明确导入您的配置:

@Slf4j
// @ExtendWith(SpringExtension.class) not needed as part of @WebMvcTest with recent Spring Boot versions
@Import(AppConfig.class)
@WebMvcTest(value = ProductController.class)
class ProductControllerTest {
   
  // your test

}

如果您依赖 MessageSource 的自动配置,您可以使用 @ImportAutoConfiguration(MessageSourceAutoConfiguration.class).

为您的测试启用它