繁体   English   中英

如何测试在Android MVP Clean Architecture中注入存储库中的sharedpreference

[英]How to test sharedpreference that inject in repository in Android MVP Clean Architecture

我在测试数据存储区中的sharedpreference时遇到问题。 在实际的数据存储区中,我实现了三个参数,其中包括sharedpreference。

在这种情况下,我想存储价值并获得价值。 嘲笑在这里没有帮助。

模拟无法传播将由代码使用的实际值。 在第二部分。

class FooDataStoreTest : Spek({
given("a foo data store") {

    val schedulerRule = TestSchedulerRule()
    val service: FooRestService = mock()
    val context: Context = mock()
    val gson: Gson = mock()
    val appFooPreference: SharedPreferences = mock()

    var appFooSessionStoreService: AppFooSessionStoreService? = null
    var fooStoredLocationService: FooStoredLocationService? = null

    beforeEachTest {
        appFooSessionStoreService = AppFooSessionStoreService.Builder()
                .context(context)
                .gson(gson)
                .preference(appFooPreference)
                .build()
        fooStoredLocationService = FooStoredLocationService(appFooSessionStoreService)
    }

    val longitude = 106.803090
    val latitude = -6.244285

    on("should get foo service with request longitude $longitude and latitude $latitude") {
        it("should return success") {
            with(fooStoredLocationService) {
                val location = Location()
                location.latitude = latitude
                location.longitude = longitude

                // i want to store location in this
                fooStoredLocationService?.saveLastKnownLocation(location)

                // and retrieve in below code
                val l = fooStoredLocationService?.lastKnownLocation

                val dataStore = FooDataStore(service, preference, fooStoredLocationService!!)
                service.getFooService(longitude, longitude) willReturnJust
                        load(FooResponse::class.java, "foo_response.json")

                val testObserver = dataStore.getFooService().test()
                schedulerRule.testScheduler.advanceTimeBy(2, TimeUnit.SECONDS)
                testObserver.assertNoErrors()
                testObserver.awaitTerminalEvent()
                testObserver.assertComplete()
                testObserver.assertValue { actual ->
                    actual == load(FooResponse::class.java, "foo_response.json")
                }
            }
        }
    }

    afterEachTest {
        appFooSessionStoreService?.clear()
        fooStoredLocationService?.clear()
    }
}})

这个数据存储看起来像

open class FooDataStore @Inject constructor(private val fooRestService: FooRestService,
                                        private val fooPreference: FooPreference,
                                        private val fooLocation: fooStoredLocationService) : FooRepository {

private val serviceLocation by lazy {
    fooLocation.lastKnownLocation
}

override fun getFooService(): Single<FooResponse> {
    safeWith(serviceLocation, {
        return getFooLocal(it).flatMap({ (code, message, data) ->
            if (data != null) {
                Single.just(FooResponse(code, message, data))
            } else {
                restService.getFooService(it.longitude, it.latitude).compose(singleIo())
            }
        })
    })
    return Single.error(httpExceptionFactory(GPS_NOT_SATISFYING))
}

}

实际上,我想从此serviceLocation获取价值。 任何人都可以为此做一些测试的方法吗?非常欢迎任何意见。

谢谢!

我建议您不要直接依赖SharedPreferences ,而是要有一些LocalStorage接口,以便可以在代码中使用SharedPrefsLocalStorage并在测试中使用TestLocalStorage SharedPrefsLocalStorage将在SharedPrefsLocalStorage使用SharedPreferences ,并TestLocalStorage一些Map实现。

只是一个简单的例子:

// You may add other type, not Int only, or use the String and convert everything to String and back
interface LocalStorage {
    fun save(key: String, value: Int)
    fun get(key: String): Int? 
}

class SharedPrefsLocalStorage(val prefs: SharedPreferences) : LocalStorage {
    override fun save(key: String, value: Int) {
        with(prefs.edit()){
            putInt(key, value)
            commit()
        }
    }
    override fun get(key: String): Int? = prefs.getInteger(key)
}

class TestLocalStorage : LocalStorage {
    val values = mutableMapOf<String, Any>()

    override fun save(key: String, value: Int) {
        values[key] = value
    }

    override fun get(key: String): Int? = map[value] as Int?
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM