我试图将基于Kotlin的示例转换为Kotlin Bean定义DSL语法。该应用程序运行良好,但测试失败。
original Kotlin sample,即转换后的Kotlin DSL sample。
像这样的bean定义。
fun beans() = beans {
bean {
CommandLineRunner {
println("start data initialization...")
val posts = ref<PostRepository>()
posts.deleteAll()
.thenMany<Post>(
posts.saveAll(
arrayListOf(
Post(null, "my first post", "content of my first post"),
Post(null, "my second post", "content of my second post")
)
)
)
.log()
.subscribe(null, null, { println("data initialization done.") })
}
}
bean {
PostRoutes(PostHandler(ref())).routes()
}
bean<PasswordEncoder> {
PasswordEncoderFactories.createDelegatingPasswordEncoder()
}
bean<SecurityWebFilterChain> {
ref<ServerHttpSecurity>().authorizeExchange()
.pathMatchers(HttpMethod.GET, "/posts/**").permitAll()
.pathMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN")
.pathMatchers("/posts/**").authenticated()
//.pathMatchers("/users/{user}/**").access(this::currentUserMatchesPath)
.anyExchange().permitAll()
.and()
.csrf().disable()
.build()
}
bean {
val passwordEncoder = ref<PasswordEncoder>()
val user = User.withUsername("user")
.passwordEncoder { it -> passwordEncoder.encode(it) }
.password("password")
.roles("USER").build()
val admin = User.withUsername("admin")
.password("password")
.passwordEncoder { it -> passwordEncoder.encode(it) }
.roles("USER", "ADMIN")
.build()
MapReactiveUserDetailsService(user, admin)
}
bean {
val config = CorsConfiguration().apply {
// allowedOrigins = listOf("http://allowed-origin.com")
// maxAge = 8000L
// addAllowedMethod("PUT")
// addAllowedHeader("X-Allowed")
}
val source = UrlBasedCorsConfigurationSource().apply {
registerCorsConfiguration("/**", config)
}
CorsWebFilter(source)
}
}
并在main函数中初始化bean。
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args) {
addInitializers(beans())
}
}
我创建了两个测试,但都没有。
@SpringBootTest(classes = arrayOf(DemoApplication::class))
class ApplicationTests {
@Autowired
private lateinit var routing: PostRoutes
private lateinit var client: WebTestClient
@BeforeAll
fun setup(){
client = WebTestClient.bindToRouterFunction(routing.routes()).build()
}
@Test
fun `get all posts`() {
client.get().uri("/posts")
.exchange().expectStatus().isOk
}
}
@SpringBootTest(classes = [DemoApplication::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class IntegrationTests {
private lateinit var client: WebClient
@LocalServerPort
private var port: Int = 8080
@BeforeAll
fun setup() {
client = WebClient.create("http://localhost:$port")
}
@Test
fun `get all posts`() {
client.get()
.uri("/posts")
.accept(MediaType.APPLICATION_JSON_UTF8)
.exchange()
.test()
.expectNextMatches { it.statusCode() == HttpStatus.OK }
.verifyComplete()
}
}
类似的测试在my general kotlin sample中工作良好。
更新:由this topic解决,并在tests中添加了自定义ApplicationContextInitializer
。