Java Can';t在Kotlin中模拟'willReturn',并带有可选项

Java Can';t在Kotlin中模拟'willReturn',并带有可选项,java,kotlin,optional,mockito-kotlin,Java,Kotlin,Optional,Mockito Kotlin,我有办法 fun getUser(userId:userId):可选=userRepository.findById(userId) 在Java中返回一个可选的。 所以我想在Kotlin单元测试中模拟该方法调用 这是我的第一个猜测 给定{mockedUserService.getUser(currentUser.userId)}.willReturn(可选的.of(currentUser)) 。。。但是编译器说没有 类型不匹配:推断类型是可选的,但可选!预料之中 因此,我开始制作val cu

我有办法

fun getUser(userId:userId):可选=userRepository.findById(userId)
在Java中返回一个可选的。 所以我想在Kotlin单元测试中模拟该方法调用

这是我的第一个猜测

给定{mockedUserService.getUser(currentUser.userId)}.willReturn(可选的.of(currentUser))
。。。但是编译器说没有

类型不匹配:推断类型是可选的,但可选!预料之中

因此,我开始制作
val currentUser:User?
,只是为了让编译器满意

给定{currentUser?.userId?.let{mockedUserService.getUser(it)}.willReturn(可选的.of(currentUser))
类型不匹配:推断类型是可选的,但应为可选类型

类型不匹配:推断的类型是User?但应为TypeVariable(T)


现在我有点迷路了。我怎样才能让编译器高兴呢?

你可以尝试willresponse而不是willReturn

given { mockedUserService.getUser(currentUser.userId) }.willAnswer { Optional.of(currentUser) }

我假设您使用的是Java的type
Optional
,而不是您自己的实现(做的比我在这里看到的更多)

Optional
出现在Java中是为了避免NPE,并在运行时指示类型不存在。但是在Kotlin中,您实际上不需要可选的,因为您可以明确地将您的类型定义为可为null的
T?

因此,您可以将其定义为:

fun getUser(userId:userId):用户?

fun getUser(userId:userId):可选//不可为空!

一种方法是修复测试,但这实际上不是问题所在。您应该尽可能避免Kotlin中的
可选
。Java的类型系统无法区分可空值和不可空值。Kotlin可以,因此您应该尽早将
可选
转换为
T?

您可以这样轻松地修复您的函数:

fun getUser(userId: UserId): User? = userRepository.findById(userId).orElse(null)

你能分享
UserService.getUser(userId:userId)的完整签名吗
包括返回类型。@ChristianB editedOkay,但为什么?有什么区别?为什么这可以工作,而前者不行?如果您需要以某种方式计算返回值,通常会使用willAnswer。它不会像willReturn那样在编译时强制执行返回值的类型。如果您在示例abo中返回字符串ve,代码仍然可以编译,但在运行时会得到ClassCastException。也就是说,这应该被视为一种解决方法。你是对的,
可选
有点多余,因为我正在考虑它,让我知道这种方法是否解决了你的测试问题。这不是一种替代方法。我想这应该是选择的答案.避免在Kotlin中使用可选选项。