3

我有一个方法

fun getUser(userId: UserId): Optional<User?> = userRepository.findById(userId)

在 Java 中返回 Optional。所以我想在我的 Kotlin 单元测试中模拟该方法调用。

这是我的第一个猜测...

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

...但编译器说不

类型不匹配:推断类型是 Optional 但 Optional<User?>! 预计

所以我开始做val currentUser: User?只是为了让编译器开心。

given { currentUser?.userId?.let { mockedUserService.getUser(it) }.willReturn(Optional.of(currentUser))

类型不匹配:推断类型是 Optional 但 Optional<User?>? 预计

类型不匹配:推断类型是用户?但 TypeVariable(T) 是预期的

现在我有点迷失了。我怎样才能让编译器满意?

4

3 回答 3

3

将此视为替代方案。我假设您使用的是 Java 的类型Optional,而不是您自己的实现(比我在这里看到的更多)。

使用OptionalJava 是为了避免 NPE 并在运行时指示类型的缺失。但在 Kotlin 中,您并不需要 Optional,因为您可以明确地将您的类型定义为 nullable T?

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

fun getUser(userId: UserId): User?

或者

fun getUser(userId: UserId): Optional<User> // not nullable!
于 2020-12-21T14:39:32.283 回答
2

您可以尝试willAnswer而不是willReturn

given { mockedUserService.getUser(currentUser.userId) }.willAnswer { Optional.of(currentUser) }
于 2020-12-21T14:30:03.280 回答
1

一种方法是修复测试,但这实际上不是这里的问题。你应该尽可能避免Optional在 Kotlin 中使用。Java 的类型系统无法区分可空值和不可空值。Kotlin 可以,因此您应该Optional<T>尽早将T?.

您可以像这样轻松地修复您的功能:

fun getUser(userId: UserId): User? = userRepository.findById(userId).orElse(null)
于 2020-12-21T15:47:20.110 回答