问题描述
我尝试对演示者进行单元测试。我有更新标记的方法,当它失败时,应用程序会显示带有已翻译消息的吐司。
override fun updateMark(cameraId: Int,markId: Int,createData: MarkCreateData,context: Context) {
view?.let {
view?.showOrHideProgressBar(true)
apimanager.updateMark(cameraId,markId,createData)
.subsIoObsMain()
.subscribe({
view?.showOrHideProgressBar(false)
view?.updateMarkSuccess()
}) {
view?.showOrHideProgressBar(false)
view?.showToast(getStringForLayoutByKey("mark_updated_fail"))
}.addTo(compositedisposable)
}
}
提供翻译的方法包含在使用首选项的 LocalData对象中。
object LocalData {
private val prefs: SharedPreferences = App.instance.getSharedPreferences(this.javaClass.simpleName,Context.MODE_PRIVATE)
fun getStringForLayoutByKey(key: String) =
if (getJsonDataServer().getByKeyOrKeySave(key).isNullOrEmpty()) {
getJsonDataClient().getByKeyOrKeySave(key) ?: ""
} else {
getJsonDataServer().getByKeyOrKeySave(key) ?: ""
}
}
使用伴随为Lateinit var的App.instance进行初始化。
class App @Inject constructor(): Application(),LifecycleObserver {
companion object {
@JvmStatic
lateinit var instance: App
@JvmField
var localData: LocalData? = null
}
override fun onCreate() {
ProcessLifecycleOwner.get().lifecycle.addobserver(this)
super.onCreate()
instance = this
localData = LocalData
buildDagger()
}
}
所以我尝试运行单元测试。
@RunWith(MockitoJUnitRunner::class)
class PlayerPresenterTest {
@Rule
@JvmField
val rule = ImmediateSchedulerRule()
@Mock
lateinit var apimanager: NetworkManager
@Mock
lateinit var playerFragment: PlayerContract.View
@Mock
lateinit var context: Context
@Mock
lateinit var unkNownError: UnkNownHostException
@Mock
lateinit var localData: LocalData
@Mock
lateinit var sharedPreferences: SharedPreferences
@Mock
lateinit var app: App.Companion
@Mock
lateinit var instance: App
//variables
private lateinit var playerPresenter: PlayerPresenter
private lateinit var markCreateData: MarkCreateData
private val errorMarkUpdate = "mark updated fail. try later"
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
MockKAnnotations.init(this,relaxUnitFun = true)
playerPresenter = PlayerPresenter()
playerPresenter.attachView(playerFragment)
playerPresenter.apimanager = apimanager
markCreateData = MarkCreateData()
}
//try update mark and get error
@Test
fun test_Failed_update_mark() {
val error = Observable.error<Mark>(unkNownError)
whenever(apimanager.updateMark(cameraId.toInt(),markId.toInt(),markCreateData)).thenReturn(error)
mockkObject(App)
every { App } returns app
every { app.instance } returns instance
every { instance.getSharedPreferences(this.javaClass.simpleName,Context.MODE_PRIVATE) } returns sharedPreferences
every { localData.getStringForLayoutByKey("mark_updated_fail") } returns errorMarkUpdate
playerPresenter.updateMark(cameraId.toInt(),markCreateData,context)
verify(playerFragment,atLeastOnce()).showToast(errorMarkUpdate)
}
}
并得到错误“由以下原因引起:kotlin.UninitializedPropertyAccessException:lateinit属性实例尚未初始化” ,它引用了LocalData私有val首选项初始化。 smb可以帮我这个忙吗? 如何在单元测试中初始化实例并避免该错误?或者也许我该如何在不使用App.instance的引用的情况下模拟LocalData对象?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)