我的视图模型拥有一个非常简单的recyclerview适配器
[当我尝试向其发送消息时(依次调用notifyDatasetChanged
)它会抛出异常,如此类
java.lang.NullPointerException
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11996)
at
问题是mObservers
中的AdapterDataObservable
变量为空
事实是,它扩展了Observable<AdapterDataObserver>
,这又将mObservers
定义为
protected final ArrayList<T> mObservers = new ArrayList<T>();
所以基本上在我的适配器实例化的那一刻,它将调用
private final AdapterDataObservable mObservable = new AdapterDataObservable();
(顺便说一下,mObservable不为null)
反过来应该叫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 }
}
下面是经过测试的代码:
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)
}
我不知道您是否已经找到解决方案,但这是针对像我这样遇到类似问题的其他人的:
将测试设为android测试(又名仪器测试)和not单元测试。
虽然我无法完全解释原因,但似乎在通知适配器有关更改(notifyItemChanged()
,notifyDataSetChanged()
等)时,有关android内部逻辑的某些信息需要实际的RecyclerView
/适配器才能接收到该消息。
一旦我将测试从Test
文件夹移至AndroidTest
文件夹,问题就已解决。
P.S。
请确保删除旧的构建配置! android studio继续引用旧的(在Test
文件夹中),如果不删除它,则会收到classNotFound
错误