Android 单元测试 LiveData.value 返回 null

Posted

技术标签:

【中文标题】Android 单元测试 LiveData.value 返回 null【英文标题】:Android Unit Test LiveData.value return null 【发布时间】:2020-06-14 02:53:38 【问题描述】:

我正在尝试使用 MVVM 架构为我的应用示例创建单元测试。在场景中,我试图为执行插入的方法创建一个测试,在这种情况下,我调用 ViewModel 方法,该方法调用存储库将文本传递给插入,然后我的存储库调用插入Dao 类,然后现在返回一个新列表,其中插入了该新项目。但在我的测试中,我的 LiveData 对象为 null

ViewModel 类

class MainViewModel(private val todoRepository: TodoRepository) : ViewModel() 
    private val _todos = MutableLiveData<List<Todo>>()
    fun observeTodos() = _todos

    fun insertNewTask(text: String)
        viewModelScope.launch 
            val result  = todoRepository.insertTask(text)
            _todos.value = result
        
    

存储库类

class TodoRepositoryImpl(context: Context): TodoRepository 

val db =
    AppDatabase.invoke(
        context
    )

    override suspend fun insertTask(text: String): List<Todo>  
        db.myDao().addItem(Todo(text = text))
        return db.myDao().getItems()
    


我的测试课

@ExperimentalCoroutinesApi
@RunWith(JUnit4::class)
class MainViewModelTest 

@Rule
@JvmField
val rule = InstantTaskExecutorRule()

private val repository = mock(TodoRepository::class.java)

private lateinit var viewModel: MainViewModel

@Before
fun setUp() 
    viewModel = MainViewModel(repository)


@Test
fun should_insertNewTodo() = runBlockingTest 

    //given
    val result = MutableLiveData<List<Todo>>()
    val returnedList = createTodoList()
    whenever(repository.getAllTodos()).thenReturn(returnedList)

    //when
    viewModel.insertNewTask("newTask")
    result.value = viewModel.observeTodos().value


    //than
    verify(repository).insertTask(anyString())
    assertEquals(returnedList, result.value)



fun createTodoList(): List<Todo>
    val mockList = listOf(Todo(id = 1, text = "FIRST", completed = false),
        Todo(id = 2, text = "SECOND", completed = false),
        Todo(id = 3, text = "THIRD", completed = true)
    )
    return mockList



我认为这很容易,但我不知道如何解决它,测试失败并给出这个答案:

Expected :[Todo(id=1, text=FIRST, completed=false), Todo(id=2, text=SECOND, completed=false), Todo(id=3, text=THIRD, completed=true)]
Actual   :null

【问题讨论】:

【参考方案1】:

为了解决这个问题,我只是错过了一件事,我的方法 viewmodel.insertTask() 不调用 repository.getAllTodos(),那么我的任何时候都错了!!!正确的是:

@Test
fun should_insertNewTodo() = runBlockingTest 

    //given
    val returnedList = createTodoList()
    whenever(repository.insertTask(anyString())).thenReturn(returnedList)

    //when
    viewModel.insertNewTask("newTask")
    val result = viewModel.observeTodos().value

    //than
    verify(repository).insertTask(anyString())
    assertEquals(returnedList, result)


【讨论】:

以上是关于Android 单元测试 LiveData.value 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Android 单元测试学习计划

Android单元测试系列-开篇

Android单元测试系列-开篇

Android Gradle 插件TestOptions 配置 ④ ( org.gradle.api.tasks.testing.Test 单元测试配置类 | Android 单元测试示例 )

Android测试:Instrumented 单元测试

Android测试:Local 单元测试