1

我为我的一个用例编写了一个基于 Spek 框架的单元测试。以下是用例代码:

class InsertRemoteWidgetUseCase(
private val remoteConfigProviderImplement: RemoteConfigProviderImplement, 
private val feedDataStore: FeedDataStoreImplement
) {

fun invoke(): ArrayList<FeedData> {
    if (remoteConfigProviderImplement.getHomeWidgetVisible()) {
        val cardData = CardData()
        cardData.url = remoteConfigProviderImplement.getHomeWidgetURL()

        val feedData = FeedData()
        feedData.type = CardType.REMOTE_CONFIG_WIDGET
        feedData.listData = arrayListOf(cardData)

        feedDataStore.insertRemoteWidgetCard(feedData)
    } else {
        feedDataStore.removeRemoteWidgetCard()
    }

    return feedDataStore.getData()
  }
}  

这是测试用例的实现:

class InsertRemoteWidgetUseCaseTest : Spek({

lateinit var mockRemoteConfigProviderImplement: RemoteConfigProviderImplement
lateinit var mockFeedDataStoreImplement: FeedDataStoreImplement

lateinit var instance: InsertRemoteWidgetUseCase

val feedComponentData1: FeedComponentData = mockk(relaxed = true)
val feedComponentData2: FeedComponentData = mockk(relaxed = true)

var remoteWidgetUrl = ""
var remoteWidgetVisible = false

val feedDataList1 = arrayListOf(
    FeedData(listItems = arrayListOf(
        CardItem(articleData = ArticleData(title = "A0"))
    )
    ),
    FeedData(listItems = arrayListOf(
        CardItem(articleData = ArticleData(title = "B0")),
        CardItem(articleData = ArticleData(title = "B1")),
        CardItem(articleData = ArticleData(title = "B2"))
    ))
)

val feedDataList2 = arrayListOf(FeedData())
val pagination1 = Pagination(current = 0, next = 1)
val pagination2 = Pagination(current = 1, next = 2)

beforeEachTest {
    every{feedComponentData1.pagination} returns pagination1
    every{feedComponentData1.feedList} returns feedDataList1

    every{feedComponentData2.pagination} returns pagination2
    every{feedComponentData2.feedList} returns feedDataList2

    mockRemoteConfigProviderImplement = mockk(relaxed = true)
    mockFeedDataStoreImplement = spyk(FeedDataStoreImplement())

    instance = spyk(InsertRemoteWidgetUseCase(mockRemoteConfigProviderImplement, mockFeedDataStoreImplement))
}

describe("invoke()") {
    context("getHomeWidgetVisible is true") {
        it("FeedData with CardType.REMOTE_CONFIG_WIDGET is inserted") {
            remoteWidgetUrl = "www.google.com"
            remoteWidgetVisible = true
            every { mockRemoteConfigProviderImplement.getHomeWidgetURL() } returns remoteWidgetUrl
            every { mockRemoteConfigProviderImplement.getHomeWidgetVisible() } returns remoteWidgetVisible

            mockFeedDataStoreImplement.update(feedComponentData1)
            mockFeedDataStoreImplement.update(feedComponentData2)

            val feedDataListBefore = mockFeedDataStoreImplement.getData()
            val feedDataListAfter = instance.invoke()

            assert(feedDataListAfter[0].type == CardType.REMOTE_CONFIG_WIDGET)
            assert(feedDataListBefore.size == feedDataListAfter.size + 1)
        }
    }

    context("getHomeWidgetVisible is false") {
        it("FeedData with CardType.REMOTE_CONFIG_WIDGET is removed") {
            remoteWidgetUrl = "www.google.com"
            remoteWidgetVisible = false
            every { mockRemoteConfigProviderImplement.getHomeWidgetURL() } returns remoteWidgetUrl
            every { mockRemoteConfigProviderImplement.getHomeWidgetVisible() } returns remoteWidgetVisible

            mockFeedDataStoreImplement.update(feedComponentData1)
            mockFeedDataStoreImplement.update(feedComponentData2)

            val feedData = FeedData()
            feedData.type = CardType.REMOTE_CONFIG_WIDGET
            mockFeedDataStoreImplement.insertRemoteWidgetCard(feedData)

            val feedDataListBefore = mockFeedDataStoreImplement.getData()
            val feedDataListAfter = instance.invoke()

            assert(feedDataListAfter[0].type != CardType.REMOTE_CONFIG_WIDGET)
            assert(feedDataListBefore[0].type == CardType.REMOTE_CONFIG_WIDGET)
            assert(feedDataListBefore.size == feedDataListAfter.size - 1)
        }
    }
}
})

有问题的测试用例在本地系统中成功运行。但是对于 Bitrise,它们都失败了:

java.lang.AssertionError: Assertion failed
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:74)
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:17)
at org.spekframework.spek2.runtime.scope.TestScopeImpl.execute(Scopes.kt:94)
at org.spekframework.spek2.runtime.Executor$execute$$inlined$executeSafely$lambda$1$1.invokeSuspend(Executor.kt:52)
at ???(Coroutine boundary.?(?)
at kotlinx.coroutines.DeferredCoroutine.await$suspendImpl(Builders.common.kt:99)
at org.spekframework.spek2.runtime.ExecutorsKt$doRunBlocking$1.invokeSuspend(executors.kt:8)
Caused by: java.lang.AssertionError: Assertion failed
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:74)
at sg.com.sph.appbt.views.bnavigation.home.InsertRemoteWidgetUseCaseTest$1$2$1$1.invoke(InsertRemoteWidgetUseCaseTest.kt:17)
at org.spekframework.spek2.runtime.scope.TestScopeImpl.execute(Scopes.kt:94)
at org.spekframework.spek2.runtime.Executor$execute$$inlined$executeSafely$lambda$1$1.invokeSuspend(Executor.kt:52)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)

问题陈述

这在本地系统上执行良好,没有错误,但在云上的 Bitrise 上失败。

  1. 对于这个本地与远程问题,是否有任何灵丹妙药解决方案。
  2. 这可能是由于不同的环境,如果是,那么应该检查所有组件的版本。
4

0 回答 0