WebTestClient 在 Spring Boot 2.4.0-M3 上获得 404,而在 2.4.0-M2 上工作正常
WebTestClient gets 404 on Spring Boot 2.4.0-M3 while works fine on 2.4.0-M2
我的测试可以在 Spring 2.4.0-M2 上正常工作,但在升级到 2.4.0-M3 后它会中断 - returns 404 对于已注册的路由。
我的应用程序:
@SpringBootApplication(proxyBeanMethods = false)
class ExampleApp
fun main(args: Array<String>) {
runApplication<ExampleApp>(
init = {
addInitializers(BeansInitializer())
},
args = args
)
}
豆类:
class BeansInitializer : ApplicationContextInitializer<GenericApplicationContext> {
@Suppress("LongMethod")
override fun initialize(applicationContext: GenericApplicationContext) {
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("/") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}
.initialize(applicationContext)
}
}
data class Foo(val status: String)
我的测试:
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = [
ExampleApp::class
]
)
class FailingTest @Autowired constructor(
context: ApplicationContext,
) {
val webTestClient: WebTestClient = WebTestClient.bindToApplicationContext(context)
.configureClient()
.build()
@Test
fun `should interact with routes`() {
webTestClient
.post()
.uri("/routes")
.bodyValue(SampleBody("123"))
.exchange()
.expectStatus()
.isOk // returns 404 on 2.4.0-M3 / passes on 2.4.0-M2
}
data class SampleBody(val id: String)
}
测试application.yml
context:
initializer:
classes: com.example.BeansInitializer
2.4.0-M3
测试失败并显示以下消息:
java.lang.AssertionError: Status expected:<200 OK> but was:<404 NOT_FOUND>
在 2.4.0-M2
他们通过了。
这些版本有什么变化吗?或者这是一个错误?
您看到的行为变化是由于 Spring Framework 在 5.3 开发过程中的改进。
默认情况下,Spring 框架将匹配一个可选的尾随路径分隔符 (/
)。这个可选的 /
应该是在你的路由中指定的路径之外的。
您有两条路线:
GET /routes/{id}
POST /routes/
支持可选的尾随路径分隔符意味着您可以向 /routes/56/
发出 get 请求(一个额外的尾随 /
),但这不应该意味着您可以向 /routes/56/
发出请求POST /routes
(删除尾随 /
)。
如果您希望能够向 /routes
和 /routes/
发出 POST
请求,您应该将路由定义为 /routes
:
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}
我的测试可以在 Spring 2.4.0-M2 上正常工作,但在升级到 2.4.0-M3 后它会中断 - returns 404 对于已注册的路由。
我的应用程序:
@SpringBootApplication(proxyBeanMethods = false)
class ExampleApp
fun main(args: Array<String>) {
runApplication<ExampleApp>(
init = {
addInitializers(BeansInitializer())
},
args = args
)
}
豆类:
class BeansInitializer : ApplicationContextInitializer<GenericApplicationContext> {
@Suppress("LongMethod")
override fun initialize(applicationContext: GenericApplicationContext) {
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("/") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}
.initialize(applicationContext)
}
}
data class Foo(val status: String)
我的测试:
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = [
ExampleApp::class
]
)
class FailingTest @Autowired constructor(
context: ApplicationContext,
) {
val webTestClient: WebTestClient = WebTestClient.bindToApplicationContext(context)
.configureClient()
.build()
@Test
fun `should interact with routes`() {
webTestClient
.post()
.uri("/routes")
.bodyValue(SampleBody("123"))
.exchange()
.expectStatus()
.isOk // returns 404 on 2.4.0-M3 / passes on 2.4.0-M2
}
data class SampleBody(val id: String)
}
测试application.yml
context:
initializer:
classes: com.example.BeansInitializer
2.4.0-M3
测试失败并显示以下消息:
java.lang.AssertionError: Status expected:<200 OK> but was:<404 NOT_FOUND>
在 2.4.0-M2
他们通过了。
这些版本有什么变化吗?或者这是一个错误?
您看到的行为变化是由于 Spring Framework 在 5.3 开发过程中的改进。
默认情况下,Spring 框架将匹配一个可选的尾随路径分隔符 (/
)。这个可选的 /
应该是在你的路由中指定的路径之外的。
您有两条路线:
GET /routes/{id}
POST /routes/
支持可选的尾随路径分隔符意味着您可以向 /routes/56/
发出 get 请求(一个额外的尾随 /
),但这不应该意味着您可以向 /routes/56/
发出请求POST /routes
(删除尾随 /
)。
如果您希望能够向 /routes
和 /routes/
发出 POST
请求,您应该将路由定义为 /routes
:
beans {
bean {
router {
"/routes".nest {
GET("/{id}") { ServerResponse.ok().bodyValue(Foo("ok")) }
POST("") { ServerResponse.ok().bodyValue(Foo("ok")) }
}
}
}
}