Affects: 3.2.2
- id("org.springframework.boot") version "3.2.2"
-
kotlin("jvm") version "1.9.22"
-
This is my requestparam to get the data from application.yml
@RequestParam(name = "size", defaultValue = "\${spring.data.web.pageable.default-page-size:10}", required = false) size: Int,
- When i try to run basic integration-test using @SpringBootTest i get following error;
Failed to convert value of type 'java.lang.String' to required type 'int'; For input string: "${spring.data.web.pageable.default-page-size:10}"
- I do have parameter defined in my yml so following works in same test;
@Value("\${spring.data.web.pageable.default-page-size}") private lateinit var pageSize: String
Comment From: senocak
I am guessing this is not related with kotlin or java because i made basic app both kotlin and java with almost every springboot3 releases and they all fail. Here is the code snippet for java and kotlin;
java:
@SpringBootApplication
public class Auth3Application {
public static void main(String[] args) {
SpringApplication.run(Auth3Application.class, args);
}
}
@Validated
@RestController
@RequestMapping("/users")
class UserController {
@GetMapping
private String allUsers(
@RequestParam(defaultValue = "${spring.data.web.pageable.default-page-size:10}", required = false) final String size
) {
return size;
}
}
// tests
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class Auth3ApplicationTests {
@Autowired private UserController userController;
@Test
void contextLoads() throws Exception {
MockMvc mockMvc = MockMvcBuilders .standaloneSetup(userController).build();
ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.get("/users"));
perform.andExpect(MockMvcResultMatchers.status().isBadRequest());
}
}
kotlin:
@SpringBootApplication
class SpringKotlinApplication
fun main(args: Array<String>) {
runApplication<SpringKotlinApplication>(*args)
}
@Validated
@RestController
@RequestMapping("/users")
class UserController {
@Value("\${spring.data.web.pageable.default-page-size}")
private lateinit var jwtExpirationInMs: String
@GetMapping
fun allUsers(
@RequestParam(defaultValue = "\${spring.data.web.pageable.default-page-size:10}", required = false) size: String
): String {
println("sizesizesizesize: $size")
return size
}
}
// test
@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserControllerTest {
@Autowired private lateinit var userController: UserController
private lateinit var mockMvc: MockMvc
@BeforeEach
fun beforeEach() {
mockMvc = MockMvcBuilders.standaloneSetup(userController).build()
}
@Test
fun givenSortColumnIsInvalid_whenPatchMe_thenThrowServerException() {
// Given
val requestBuilder: RequestBuilder = MockMvcRequestBuilders
.get("/users")
// When
val perform: ResultActions = mockMvc.perform(requestBuilder)
// Then
perform.andExpect(MockMvcResultMatchers.status().isBadRequest)
}
}
Comment From: snicoll
Please move all that code in text in a sample we can actually run. The Java sample is enough.
Comment From: senocak
Please move all that code in text in a sample we can actually run. The Java sample is enough.
The code can be run straightly, please tell me what else should i provide?
Comment From: snicoll
A sample application we can run that reproduces the problem in the form of a zip file attached to this issue. Alternatively, you can push the code to GitHub and share the url of the repo here.
Comment From: senocak
Okay so i figured out that problem occurs when i configure MockMvc manually like;
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
Changing it with @AutoConfigureMockMvc
works ok.
Main app;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Validated
@RestController
@RequestMapping("/users")
class UserController {
@GetMapping
private String allUsers(
@RequestParam(defaultValue = "${spring.data.web.pageable.default-page-size:10}", required = false) final String size
) {
return size;
}
}
Failed one
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {
@Autowired private UserController userController;
@Test
void contextLoads() throws Exception {
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.get("/users"));
perform.andExpect(MockMvcResultMatchers.status().isBadRequest());
}
}
Success one;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
class DemoApplicationTests {
@Autowired private MockMvc mockMvc;
@Test
void contextLoads() throws Exception {
ResultActions perform = mockMvc.perform(MockMvcRequestBuilders.get("/users"));
perform.andExpect(MockMvcResultMatchers.status().isBadRequest());
}
}
If this is expected then issue can be closed, if not please let me know how.
Comment From: snicoll
A standalone setup has no link with the context or its environment so that is expected. Please review the javadoc of standaloneSetup, you should not create a context at all for this but create the controller manually.
If you need a controller that’s linked to the context you should not use this, but inject MockMvc as the working setup shows.
Comment From: senocak
@snicoll If thats the case, why can i get the exact same variable using @Value annotation. I would expect same result as it is.
I know injection is not working it just use default value for @Value annotation, i am asking why default is not working in @RequestParam as well
Comment From: snicoll
Because the controller instance is created by the context of your integration test, so @Value
just works as expected. However you're passing that instance into a MockMvc standalone setup and I already explained why that doesn't use the existing context and asked you to review the Javadoc.
If you have further questions, please follow-up on StackOverflow, as mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements.