I created a single MessageSourceConfig like below:
@Configuration
public class MessageSourceConfig {
@Value("${spring.messages.basename}")
private String[] basenames;
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames(basenames);
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
return messageSource;
}
}
and typical controller like TodoController:
@RestController
@RequestMapping("api/v1/todos")
@RequiredArgsConstructor
public class TodoController {
private final GetTodosUseCaseHandler getTodosUseCaseHandler;
@GetMapping("all")
public ResponseEntity<List<TodoResponseDto>> getAllTodos() {
List<TodoAggregate> todos = getTodosUseCaseHandler.handle();
return ResponseEntity.ok(TodoMapper.INSTANCE.aggregateListToTodoResponseDtoList(todos));
}
}
and finally created a ControllerTest with WebMvcTest:
@WebMvcTest(controllers = TodoController.class)
@ContextConfiguration(classes = {MessageSourceConfig.class, TodoController.class},
initializers = ConfigDataApplicationContextInitializer.class)
class TodoControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private GetTodosUseCaseHandler getTodosUseCaseHandler;
@MockBean
private CreateTodoUseCaseHandler createTodoUseCaseHandler;
private static final Long TODO_ID_1 = 1L;
@Test
void getAllTodos_success() throws Exception {
List<TodoAggregate> results = List.of(createAggregate());
when(getTodosUseCaseHandler.handle()).thenReturn(results);
mockMvc.perform(get("/api/v1/todos/all"))
.andExpect(status().isOk())
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$.[0].id", is(TODO_ID_1.intValue())))
.andExpect(jsonPath("$", hasSize(1)));
verify(getTodosUseCaseHandler).handle();
}
}
While testing my application, when I try to reach messageSource -> basenames param doesn't work properly. basenames return like ${spring.messages.basename}
is there any suggestion?
spring.messages.basename=messages
Expexted Output for ${spring.messages.basename}
is messages
but it was ${spring.messages.basename}
Interesting but @Value
doesn't work for this case. Find two different solutions:
Solution 1: (Using environment)
@Configuration
@RequiredArgsConstructor
public class MessageSourceConfig {
private final Environment environment;
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
String[] basenames = environment.getProperty("spring.messages.basename", String[].class);
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames(basenames);
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
return messageSource;
}
}
Solution 2: (Using @ConfigurationProperties
)
@Configuration
@RequiredArgsConstructor
public class MessageSourceConfig {
@Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
public MessageSourceProperties sourceProperties() {
return new MessageSourceProperties();
}
@Bean
public ReloadableResourceBundleMessageSource messageSource(MessageSourceProperties sourceProperties) {
String[] basenames = StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(sourceProperties.getBasename()));
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames(basenames);
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
return messageSource;
}
}