我正在尝试为需要经过身份验证的用户的控制器方法编写测试, 这是它的样子:
@Controller("/api/task")
class TaskController(
private val taskCompletionService: TaskCompletionService,
private val userSecurityService: UserSecurityService
) {
@Post("/{id}")
suspend fun completeTask(
@PathVariable id: Long,
@Body request: TaskCompletionRequestDTO
) {
taskCompletionService.completeTask(
taskId = id,
userId = userSecurityService.getUserId(),
action = request.action
)
}
}
我正在努力嘲笑 UserSecurityService
@Singleton
class UserSecurityService {
fun getUserId(): Int = getUserIdOrNull() ?: throw UserIdNotFoundException("UserId not found")
fun getUserIdOrNull(): Int? = getPrincipal()?.attributes?.get(PrincipalAttribute.USER_ID)?.toString()?.toInt()
@OptIn(ExperimentalStdlibApi::class)
private fun getPrincipal(): Authentication? =
(ServerRequestContext.currentRequest<Any?>().get().userPrincipal.getOrNull()) as? Authentication
@OptIn(ExperimentalStdlibApi::class)
fun isAuthorized(): Boolean {
val principal =
ServerRequestContext.currentRequest<HttpRequest<*>>()
.getOrNull()
?.attributes?.get(HttpAttributes.PRINCIPAL.toString(), Authentication::class.java)
return principal != null && !principal.isEmpty
}
}
@Replaces(UserSecurityService::class)
@Bean
fun userSecurityService(): UserSecurityService = mock()
和存根
whenever(userSecurityService().getUserId()).thenReturn(123)
,但不知何故
getUserId()
总是返回 0,所以我认为这种存根不起作用(
情况很复杂,因为我有几个 HTTP 过滤器需要访问有关经过身份验证的用户的数据(通过
UserSecurityService
)。在实际应用程序中,我使用 JWT 令牌,但在测试中我无法使用生产令牌
micronaut:
security:
token:
jwt:
claims-validators:
issuer: https://mysecretproject.com/auth
signatures:
secret:
generator:
secret: ${SECURITY_TOKEN}
理想情况下,我想在 Spring 中使用类似于
@WithMockUser
的东西,我可以在其中模拟用户身份验证,而不需要真正的 JWT 令牌。 Micronaut 有没有办法在测试中模拟 JWT 身份验证或绕过令牌验证?
预先感谢您的帮助!
不是我的存储库,但我通过以下方式成功实现了它:
https://github.com/lstoeferle/micronaut-jwt-auth-mock
基本上,您可以将
TokenAuthenticationFetcher
替换为您自己的,并且可以使用用户和给定角色对身份验证进行硬编码。