2017-03-17 40 views
4

我正在使用PowerMock和Roboelectric,並且想嘲笑類的伴侶對象函數。當我這樣做,我得到一個錯誤:kotlin中的嘲諷伴侶對象函數

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剛返回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函數?

+0

我會刪除Robolectric標籤,因爲它只是關於Kotlin和反射的問題。 –

+0

夠公平的,我不確定班加載器是否與它有關。 – TheHebrewHammer

回答

2

我最終什麼事做......

而不是嘲笑我結束了使用PowerMockito的whenNew函數返回的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)) 
    } 
}