2 votes

Impossible d'exécuter le test Robolectric dans Android Studio en utilisant Realm + PowerMockito

J'utilisais Realm, PowerMockito et Robolectric pour écrire des tests pour mon application. Le test fonctionne bien si j'utilise ./gradlew test mais si j'utilise la configuration dans Android Studio. Il y aura une erreur comme ci-dessous.

com.thoughtworks.xstream.converters.ConversionException: Cannot construct org.powermock.modules.junit4.rule.PowerMockStatement$1 as it does not have a no-args constructor : Cannot construct org.powermock.modules.junit4.rule.PowerMockStatement$1 as it does not have a no-args constructor

Quelqu'un a-t-il une solution pour ce problème ? Voici le test que j'ai écrit en Kotlin.

@RunWith(RobolectricGradleTestRunner::class)
@Config(application = TestApplication::class, constants = BuildConfig::class, sdk = intArrayOf(21))
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*")
@SuppressStaticInitializationFor("io.realm.internal.Util")
@PrepareForTest(RealmCore::class, RealmLog::class, Realm::class, RealmResults::class, RealmQuery::class)
class RealmMiddlewareTest {

    data class TestState(var item: List<Item> = listOf())

    lateinit var realmMock: Realm

    lateinit var mockRealmResults: RealmResults<Item>

    val mockResults = arrayListOf(
            Item().apply {
                title = "item#1"
            },
            Item().apply {
                title = "item#2"
            },
            Item().apply {
                title = "item#3"
            }
    )

    @get:Rule
    val rule = PowerMockRule()

    @Before
    fun setUp() {
        PowerMockito.mockStatic(RealmCore::class.java)
        PowerMockito.mockStatic(RealmLog::class.java)
        PowerMockito.mockStatic(Realm::class.java)
        PowerMockito.mockStatic(RealmResults::class.java)
        Realm.init(RuntimeEnvironment.application)
        // Create the mock
        realmMock = PowerMockito.mock(Realm::class.java)

        // TODO: Better solution would be just mock the RealmConfiguration.Builder class. But it seems there is some
        // problems for powermock to mock it (static inner class). We just mock the RealmCore.loadLibrary(Context) which
        // will be called by RealmConfiguration.Builder's constructor.
        PowerMockito.doNothing().`when`(RealmCore::class.java)
        RealmCore.loadLibrary(Matchers.any(Context::class.java))
        `when`(Realm.getDefaultInstance()).thenReturn(realmMock)

        mockRealmResults = PowerMockito.mock(RealmResults::class.java) as RealmResults<Item>

        val mockQuery = PowerMockito.mock(RealmQuery::class.java)
        `when`(realmMock.where(Item::class.java)).thenReturn(mockQuery as RealmQuery<Item>)
        `when`(mockQuery.findFirst()).thenReturn(mockResults[0])
        `when`(mockQuery.findAll()).thenReturn(mockRealmResults)

        `when`(mockRealmResults.iterator()).thenReturn(mockResults.iterator())
        `when`(mockRealmResults.size).thenReturn(mockResults.size)

    }

    @Test
    fun realm_transaction_action_successfully_committed() {
        val testReducer = ReducerFn<TestState> { state, action ->
            if (action is RealmTransactionAction.Committed) {
                if (action.payloadType == Item::class.java.canonicalName) {
                    assertThat(action.payload as Item, sameInstance(mockResults[0]))
                }
            }
            state
        }
        val store = SimpleStore(TestState(), testReducer).applyMiddleware(RealmMiddleware())

        val transaction: (Realm) -> Item = {
            it.copyToRealm(mockRealmResults[0])
        }

        val action = RealmTransactionAction.create(transaction = transaction)
        store.dispatch(action)

        verify(realmMock, times(1)).executeTransaction(Mockito.any())
        verify(realmMock, times(1)).close()
    }

    @RealmClass
    open class Item() : RealmObject() {
        open var title: String = ""
    }
}

8voto

Enuviel Points 141
testCompile 'org.powermock:powermock-module-junit4:1.6.5'
testCompile 'org.powermock:powermock-module-junit4-rule:1.6.5'
testCompile 'org.powermock:powermock-api-mockito:1.6.5'
testCompile 'org.powermock:powermock-classloading-xstream:1.6.5'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X