在 kotlin 中模拟伴随对象函数
Mocking companion object function in kotlin
我正在使用 PowerMock 和 Roboelectric,并想为 class 模拟一个伴随对象函数。当我这样做时,出现错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
我的基本上是这样的:
open class MockableClass private constructor(context: Context) {
companion object {
private val INSTANCE_LOCK = Any()
private var sInstance: MockableClass? = null
@JvmStatic
fun getInstance(context: Context): MockableClass? {
synchronized(INSTANCE_LOCK) {
sInstance = (sInstance ?: MockableClass(context).let {
if (it.isValid) it
else null
}
}
return sInstance
}
}
init {
// Do some initialization using context...
// Set isValid to true/false depending on success
}
val isValid: Boolean
}
当我去测试它时,我会假设它总是有效,并且希望 getInstance 只是 return MockableClass
.
的模拟版本
@RunWith(RobolectricTestRunner::class)
@Config(manifest = "src/main/AndroidManifest.xml",
constants = BuildConfig::class,
sdk = intArrayOf(23))
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*")
@PrepareForTest(MockableClass::class)
class MyTest {
private lateinit var context: Context
@get:Rule
val rule = PowerMockRule()
@Before
fun setUp() {
context = RuntimeEnvironment.application as Context
}
@Test
fun test() {
val instance = mock(MockableClass::class.java)
mockStatic(MockableClass::class.java)
`when`(MockableClass.getInstance(Matchers.isA(Context::class.java)))
.thenReturn(instance)
assertEquals(instance,
MockableClass.getInstance(RuntimeEnvironment.application as Context))
}
}
我也试过嘲笑 MockableClass.Companion::class.java 但没有成功。
有人知道我需要做什么才能模拟这个 getInstance
函数吗?
我最后做了什么...
我没有模拟静态方法,而是使用 PowerMockito 的 whenNew
函数来 return MockableClass
的模拟实例。最终代码如下所示:
@RunWith(RobolectricTestRunner::class)
@Config(manifest = "src/main/AndroidManifest.xml",
constants = BuildConfig::class,
sdk = intArrayOf(23))
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*")
@PrepareForTest(MockableClass::class)
class MyTest {
private lateinit var context: Context
@JvmField
@Rule
var rule = PowerMockRule()
@Before
fun setUp() {
context = RuntimeEnvironment.application as Context
}
@Test
fun test() {
val instance = mock(MockableClass::class.java)
instance.isValid = true
whenNew<MockableClass>("com.example.MockableClass")
.withAnyArguments()
.thenReturn(instance)
assertEquals(instance, MockableClass.getInstance(context))
}
}
我正在使用 PowerMock 和 Roboelectric,并想为 class 模拟一个伴随对象函数。当我这样做时,出现错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
我的基本上是这样的:
open class MockableClass private constructor(context: Context) {
companion object {
private val INSTANCE_LOCK = Any()
private var sInstance: MockableClass? = null
@JvmStatic
fun getInstance(context: Context): MockableClass? {
synchronized(INSTANCE_LOCK) {
sInstance = (sInstance ?: MockableClass(context).let {
if (it.isValid) it
else null
}
}
return sInstance
}
}
init {
// Do some initialization using context...
// Set isValid to true/false depending on success
}
val isValid: Boolean
}
当我去测试它时,我会假设它总是有效,并且希望 getInstance 只是 return MockableClass
.
@RunWith(RobolectricTestRunner::class)
@Config(manifest = "src/main/AndroidManifest.xml",
constants = BuildConfig::class,
sdk = intArrayOf(23))
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*")
@PrepareForTest(MockableClass::class)
class MyTest {
private lateinit var context: Context
@get:Rule
val rule = PowerMockRule()
@Before
fun setUp() {
context = RuntimeEnvironment.application as Context
}
@Test
fun test() {
val instance = mock(MockableClass::class.java)
mockStatic(MockableClass::class.java)
`when`(MockableClass.getInstance(Matchers.isA(Context::class.java)))
.thenReturn(instance)
assertEquals(instance,
MockableClass.getInstance(RuntimeEnvironment.application as Context))
}
}
我也试过嘲笑 MockableClass.Companion::class.java 但没有成功。
有人知道我需要做什么才能模拟这个 getInstance
函数吗?
我最后做了什么...
我没有模拟静态方法,而是使用 PowerMockito 的 whenNew
函数来 return MockableClass
的模拟实例。最终代码如下所示:
@RunWith(RobolectricTestRunner::class)
@Config(manifest = "src/main/AndroidManifest.xml",
constants = BuildConfig::class,
sdk = intArrayOf(23))
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*")
@PrepareForTest(MockableClass::class)
class MyTest {
private lateinit var context: Context
@JvmField
@Rule
var rule = PowerMockRule()
@Before
fun setUp() {
context = RuntimeEnvironment.application as Context
}
@Test
fun test() {
val instance = mock(MockableClass::class.java)
instance.isValid = true
whenNew<MockableClass>("com.example.MockableClass")
.withAnyArguments()
.thenReturn(instance)
assertEquals(instance, MockableClass.getInstance(context))
}
}