等价于 doReturn(x).when(y)... 在 mockk 中?
Equivalent of doReturn(x).when(y)... in mockk?
我正在寻找等价于 doReturn(...).when(...).*
的 mockk
我正在编写一些涉及大量系统的单元测试(测试合同)类,因此需要拦截我无法控制的方法和 return 一些回调(代码中的方法最终会 returned)。在 mockito 中,我可以做类似 doReturn(...).when(...).*
我没能在 mockK 中找到类似的东西。似乎每个{} 总是在答案或 returns.
之前运行块
class Vehicle: Listener {
fun displayCar(listener:Listener){
OtherClass().fetchCar(listener)
}
override fun showCarSuccessful() {
//do something
}
}
class OtherClass {
//assume its an outside function that returns nothing but invokes a method of listener call back
fun fetchCar(listener: Listener) {
//... Some system level operations that I don't have control to generate mock objects but in the test I want to use the listener to call some method so that I can
// test some contracts
listener.showCarSuccessful()
}
}
class Tests {
@Test
fun testCarSuccess() {
val listener: Listener = mockk(relaxed = true)
val vehicle = Vehicle()
//also tried with mockkClass and others
val other: OtherClass = mockk(relaxed = true)
every { other.fetchCar(listener) } returns {listener.showCarSuccessful()}
vehicle.displayCar(listener)
//do some verification checks here
}
}
interface Listener {
fun showCarSuccessful()
}
every{}
块是您的 when
子句。您可以为 returning 不同的结果设置多个条件。请参阅设置固定 returns
和执行编程 answers
的示例
import io.mockk.MockKException
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class MyClass {
fun add(operand1: Int, operand2: Int): Int {
TODO()
}
}
class MockkTest {
@Test
fun testMocking() {
val myClassMock = mockk<MyClass> {
every { add(1, 2) } returns 3 // Set behaviour
every { add(2, 2) } returns 4 // Set behaviour
every { add(3, 4)} answers {args[0] as Int * args[1] as Int} // Programmatic behaviour
}
Assertions.assertEquals(3, myClassMock.add(1, 2))
Assertions.assertEquals(4, myClassMock.add(2, 2))
Assertions.assertEquals(12, myClassMock.add(3, 4))
Assertions.assertThrows(MockKException::class.java) {
myClassMock.add(5, 6) // This behaviour has not been set up.
}
}
}
但是,特别是在您的示例中,我发现了这一行:
every { other.fetchCar(listener) } returns listener.showCarSuccessful()
很奇怪。首先,它并没有按照您的想法进行操作 - 它会在您设置此行为时进行调用,您告诉您的模拟 return 该调用的结果,而不是执行该调用。做你想做的事,你应该这样做:
every { other.fetchCar(listener) } answers {listener.showCarSuccessful()}
但即便如此,在您调用测试中的 class 之后,此行仍在设置模拟行为 - 首先设置您的模拟行为。
此外,您在嵌套模拟中的顶级模拟中设置副作用很奇怪。当然,为了测试您的 Vehicle
class,您要做的就是验证其内部 class 是否使用正确的参数调用。另外,Vehicle
是如何获得对您的 OtherClass
模拟的引用的,它正在实例化一个新模拟并调用该函数。
下面是使您的示例工作的尝试:
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Test
interface Listener {
fun showCarSuccessful()
}
class Vehicle(val other: OtherClass) : Listener {
fun displayCar(listener: Listener) {
other.fetchCar(listener)
}
override fun showCarSuccessful() {
//do something
}
}
class OtherClass {
//assume its an outside function that returns nothing but invokes a method of listener call back
fun fetchCar(listener: Listener) {
}
}
class VehicleTest{
@Test
fun testDisplayCar(){
val listener: Listener = mockk(relaxed = true)
val other: OtherClass = mockk(relaxed = true) //also tried with mockkClass and others
val vehicle = Vehicle(other)
vehicle.displayCar(listener)
verify{ other.fetchCar(listener) }
}
}
即便如此,我认为可能还有点偏差 - 我怀疑您希望 Vehicle
传递给 OtherClass
的侦听器本身,而不是参数...
然后您还应该为 OtherClass
编写一个单独的测试,以确保它在您调用 fetchCar
时按照您的预期执行
我正在寻找等价于 doReturn(...).when(...).*
的 mockk我正在编写一些涉及大量系统的单元测试(测试合同)类,因此需要拦截我无法控制的方法和 return 一些回调(代码中的方法最终会 returned)。在 mockito 中,我可以做类似 doReturn(...).when(...).*
我没能在 mockK 中找到类似的东西。似乎每个{} 总是在答案或 returns.
之前运行块 class Vehicle: Listener {
fun displayCar(listener:Listener){
OtherClass().fetchCar(listener)
}
override fun showCarSuccessful() {
//do something
}
}
class OtherClass {
//assume its an outside function that returns nothing but invokes a method of listener call back
fun fetchCar(listener: Listener) {
//... Some system level operations that I don't have control to generate mock objects but in the test I want to use the listener to call some method so that I can
// test some contracts
listener.showCarSuccessful()
}
}
class Tests {
@Test
fun testCarSuccess() {
val listener: Listener = mockk(relaxed = true)
val vehicle = Vehicle()
//also tried with mockkClass and others
val other: OtherClass = mockk(relaxed = true)
every { other.fetchCar(listener) } returns {listener.showCarSuccessful()}
vehicle.displayCar(listener)
//do some verification checks here
}
}
interface Listener {
fun showCarSuccessful()
}
every{}
块是您的 when
子句。您可以为 returning 不同的结果设置多个条件。请参阅设置固定 returns
和执行编程 answers
import io.mockk.MockKException
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class MyClass {
fun add(operand1: Int, operand2: Int): Int {
TODO()
}
}
class MockkTest {
@Test
fun testMocking() {
val myClassMock = mockk<MyClass> {
every { add(1, 2) } returns 3 // Set behaviour
every { add(2, 2) } returns 4 // Set behaviour
every { add(3, 4)} answers {args[0] as Int * args[1] as Int} // Programmatic behaviour
}
Assertions.assertEquals(3, myClassMock.add(1, 2))
Assertions.assertEquals(4, myClassMock.add(2, 2))
Assertions.assertEquals(12, myClassMock.add(3, 4))
Assertions.assertThrows(MockKException::class.java) {
myClassMock.add(5, 6) // This behaviour has not been set up.
}
}
}
但是,特别是在您的示例中,我发现了这一行:
every { other.fetchCar(listener) } returns listener.showCarSuccessful()
很奇怪。首先,它并没有按照您的想法进行操作 - 它会在您设置此行为时进行调用,您告诉您的模拟 return 该调用的结果,而不是执行该调用。做你想做的事,你应该这样做:
every { other.fetchCar(listener) } answers {listener.showCarSuccessful()}
但即便如此,在您调用测试中的 class 之后,此行仍在设置模拟行为 - 首先设置您的模拟行为。
此外,您在嵌套模拟中的顶级模拟中设置副作用很奇怪。当然,为了测试您的 Vehicle
class,您要做的就是验证其内部 class 是否使用正确的参数调用。另外,Vehicle
是如何获得对您的 OtherClass
模拟的引用的,它正在实例化一个新模拟并调用该函数。
下面是使您的示例工作的尝试:
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.Test
interface Listener {
fun showCarSuccessful()
}
class Vehicle(val other: OtherClass) : Listener {
fun displayCar(listener: Listener) {
other.fetchCar(listener)
}
override fun showCarSuccessful() {
//do something
}
}
class OtherClass {
//assume its an outside function that returns nothing but invokes a method of listener call back
fun fetchCar(listener: Listener) {
}
}
class VehicleTest{
@Test
fun testDisplayCar(){
val listener: Listener = mockk(relaxed = true)
val other: OtherClass = mockk(relaxed = true) //also tried with mockkClass and others
val vehicle = Vehicle(other)
vehicle.displayCar(listener)
verify{ other.fetchCar(listener) }
}
}
即便如此,我认为可能还有点偏差 - 我怀疑您希望 Vehicle
传递给 OtherClass
的侦听器本身,而不是参数...
然后您还应该为 OtherClass
编写一个单独的测试,以确保它在您调用 fetchCar