Cru*_*ces 8 android unit-testing android-recyclerview
我的视图模型包含一个非常简单的 recyclerview 适配器
当我尝试向它发送消息(依次调用notifyDatasetChanged)时,它会抛出这样的异常
java.lang.NullPointerException
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11996)
at
Run Code Online (Sandbox Code Playgroud)
问题是mObservers变量 fromAdapterDataObservable为空
问题是这扩展了Observable<AdapterDataObserver>它反过来定义mObservers为
protected final ArrayList<T> mObservers = new ArrayList<T>();
Run Code Online (Sandbox Code Playgroud)
所以基本上我的适配器被实例化的那一刻,它会调用
private final AdapterDataObservable mObservable = new AdapterDataObservable();
Run Code Online (Sandbox Code Playgroud)
(顺便调用,mObservable 不为空)
反过来应该调用 mObservers = new ArrayList<T>();
有人可以解释为什么从不调用它吗?或者是否有办法解决这个问题?
作为旁注,适配器不是模拟的,它是一个实体对象。
编辑:
这是我正在使用的测试代码:
class LoginViewModelTest {
private lateinit var vm: LoginViewModel
@get:Rule
val rule = InstantTaskExecutorRule()
@Before
fun setUp() {
whenever(settings.hasShownWelcome).thenReturn(false)
whenever(settings.serverIp).thenReturn("http://127.0.0.1")
//this is where the crash happens
vm = LoginViewModel(settings, service, app, TestLog, TestDispatchers) { p -> permissionGranted }
}
Run Code Online (Sandbox Code Playgroud)
下面是经过测试的代码:
class LoginViewModel(private val settings: ISettings, private val service: AppService, application: Application, l: ILog, dispatchers: IDispatchers, val permissionChecker: (String) -> Boolean) : BaseViewModel(application, l, dispatchers)
val stepAdapter :StepAdapter
init {
val maxSteps = calculateSteps()
//after this assignment, during the normal run, the stepAdapter.mObservable.mObservers is an empty array
//during unit tests, after this assignment it is null
stepAdapter = StepAdapter(maxSteps)
}
Run Code Online (Sandbox Code Playgroud)
我不知道您是否已经找到解决方案,但这适用于像我这样遇到类似问题的其他人:
使测试成为android 测试(又名仪表测试)而不是单元测试。
虽然我无法完全解释原因,但似乎当通知适配器有关更改(notifyItemChanged()等notifyDataSetChanged())时,有关 android 内部逻辑的某些内容需要实际的RecyclerView/adapter 来接收消息。
一旦我将测试从Test文件夹移动到AndroidTest文件夹,问题就解决了。
聚苯乙烯
确保删除旧的构建配置!android studio 一直引用旧的(在Test文件夹中),如果你不删除它,你会收到一个classNotFound错误
| 归档时间: |
|
| 查看次数: |
679 次 |
| 最近记录: |