我正在尝试使用Mockito在Kotlin中模拟一个通用接口。但到目前为止,我找不到自然的解决方案。给出:
interface X<T> {
fun x(): T
}
fun f(x: X<Int>) = x.x()
我可以使用以下任何一种方式模拟X
:
val x = f(Mockito.mock(X::class.java) as X<Int>)
但是这会产生一个&#34;未经检查的演员&#34;警告。
@Mock lateinit var x: X<Int>
但我不想使用@Mock
注释,因为我希望我的字段最终。
引入辅助函数,如mockito-kotlin library所做的那样:
inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java)!!
然后这样称呼:
val x: X<Int> = mock()
但我不想使用帮助函数。
是否有一种优雅的纯Kotlin方式来模拟与Mockito的通用界面? (我更喜欢没有警告的版本1.)
答案 0 :(得分:3)
只需使用mockito-kotlin项目。这个项目包含了mockito的所有必须帮助者。并支持mockito 2.1。
UPD。要处理“uncheked cast”,请使用Reified type parameters。
你说“但我不想使用辅助功能。”,但为什么呢?这是内联函数,因此在编译时函数将在所有调用站点内联。
答案 1 :(得分:0)
或者,您可以使用Mockk库。
它支持注释,因此创建一个模拟就足以编写:
@ExtendWith(MockKExtension::class)
class BookSpec {
@MockK
lateinit var author: Author
}
然后记录一些行为:
every { author.name() } returns "Milosz Brzezinski"
或
every { author.rank() } throws OutOfScaleException()
答案 2 :(得分:0)
mockito-kotlin库确实避免了警告(如果使用得当的话)。
这里是一个例子。在Maven pom.xml
中,导入库:
<dependency>
<groupId>com.nhaarman.mockitokotlin2</groupId>
<artifactId>mockito-kotlin</artifactId>
<version>2.2.0</version>
</dependency>
然后在测试中,导入模拟方法:
import com.nhaarman.mockitokotlin2.moc
然后,您可以轻松模拟任何需要模拟的东西:
@Before
fun setUp() {
val sessionFactory: FactoryBean<SessionFactory> = mock()
val eventDateReminderService: EventDateReminderService = mock()
val eventDateService: EventDateService = mock()
val templateService: TemplateService = mock()
reminderService = ReminderService(sessionFactory, eventDateReminderService, eventDateService, templateService)
}
无需强制转换或禁止显示警告。如果直接使用Mockito库,则需要强制转换并禁止显示警告。