Reputation: 167
I have a Springboot app with REST controller and Mockito unit test cases written for it. The problem is I am getting NoSuchMessageException by reading messageSource in the RestController when running the test cases. But not happening when calling it in actually using Postman or other Rest clients. (I use Lombok to avoid boilerplate codes).
The Rest Controller code
@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());
}
}
The messageSource Config
@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;
}
}
Test 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());
}
}
Exception
org.springframework.context.NoSuchMessageException: No message found under code 'success.confirmation.common.added.code' for locale 'en_US'.
But above message exists and successfully appears in actual REST clients.
Project structure
Thanks in advance.
Upvotes: 5
Views: 2814
Reputation: 12051
The @WebMvcTest
annotation only loads relevant beans (e.g. Filter
, @ControllerAdvice
, WebMvcConfigurer
) for testing your controller. By default, this TestContext doesn't include any custom @Configuration
beans.
You have explicitly import your config:
@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
}
In case you're relying on the auto-configuration of the MessageSource
you can enable it for your test with @ImportAutoConfiguration(MessageSourceAutoConfiguration.class)
.
Upvotes: 6