You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android LiveData测试:如何校验Category列表是否为空?能否用Mockito?

Great question! Let's break down how to test that your LiveData<List<Category>> returns a non-empty list, and whether Mockito is useful here.

Testing LiveData<List> for Non-Empty List

First, let's cover how to properly test your existing MockCategoriesRepository to verify the returned list isn't empty. Then we'll address the Mockito question.

Testing Your Current Mock Repository

When working with LiveData in unit tests, you need to ensure the LiveData has an active observer to guarantee the value is delivered (even if it's set synchronously like in your mock). Here's how to adjust your test:

Option 1: Without Mockito (Using a Custom Observer)

If you don't want to bring in Mockito just for this test, you can capture the LiveData value with a simple custom observer:

@Test
public void getAllCategories_returnsNonEmptyList() {
    // Set up your mock repository
    CategoriesRepository categoriesRepository = new MockCategoriesRepository();
    LiveData<List<Category>> allCategories = categoriesRepository.getAllCategories();
    
    // Create a way to capture the emitted list
    final List<Category>[] capturedCategories = new List[1];
    Observer<List<Category>> testObserver = categories -> capturedCategories[0] = categories;
    
    // Start observing the LiveData (observeForever works for unit tests since there's no lifecycle)
    allCategories.observeForever(testObserver);
    
    // Now assert the captured list is valid
    assertNotNull("Categories list should not be null", capturedCategories[0]);
    assertFalse("Categories list should not be empty", capturedCategories[0].isEmpty());
    assertEquals("Categories list should have 3 items", 3, capturedCategories[0].size());
    
    // Clean up: remove the observer to avoid test leaks
    allCategories.removeObserver(testObserver);
}

Option 2: With Mockito (Using a Mock Observer)

If you already use Mockito in your test suite, you can use it to verify the observer was called and then check the value:

@Test
public void getAllCategories_returnsNonEmptyList_withMockito() {
    CategoriesRepository categoriesRepository = new MockCategoriesRepository();
    LiveData<List<Category>> allCategories = categoriesRepository.getAllCategories();
    
    // Create a mock Observer with Mockito
    Observer<List<Category>> mockObserver = Mockito.mock(Observer.class);
    allCategories.observeForever(mockObserver);
    
    // Verify the observer received an update
    Mockito.verify(mockObserver).onChanged(Mockito.anyList());
    
    // Get the value directly from LiveData and assert
    List<Category> categories = allCategories.getValue();
    assertNotNull(categories);
    assertFalse(categories.isEmpty());
    
    allCategories.removeObserver(mockObserver);
}

Do You Need Mockito for This?

In your current setup, you don't strictly need Mockito—your handwritten MockCategoriesRepository works perfectly fine for this test. However, Mockito can simplify things if you want to avoid maintaining a separate mock class.

For example, instead of writing MockCategoriesRepository, you could mock the CategoriesRepository interface directly with Mockito:

@Test
public void getAllCategories_returnsNonEmptyList_withMockitoMockedRepo() {
    // Mock the repository interface
    CategoriesRepository mockRepo = Mockito.mock(CategoriesRepository.class);
    
    // Create your test data
    List<Category> testCategories = Arrays.asList(new Category(), new Category(), new Category());
    MutableLiveData<List<Category>> mockLiveData = new MutableLiveData<>(testCategories);
    
    // Stub the repository method to return our test LiveData
    Mockito.when(mockRepo.getAllCategories()).thenReturn(mockLiveData);
    
    // Get the result from the mocked repo
    LiveData<List<Category>> result = mockRepo.getAllCategories();
    
    // Assert the result is valid (using the same observer approach as before)
    final List<Category>[] captured = new List[1];
    result.observeForever(categories -> captured[0] = categories);
    
    assertNotNull(captured[0]);
    assertFalse(captured[0].isEmpty());
    
    result.removeObserver(categories -> captured[0] = categories);
}

This way, you don't have to write and maintain a full mock class—Mockito handles stubbing the method's return value for you.

Key Takeaways

  • LiveData Requires Observation: Always observe LiveData in tests to ensure the value is delivered. observeForever is ideal for unit tests since there's no Android lifecycle involved.
  • Assertions: Use standard JUnit assertions (or AssertJ for more readable messages) to validate the list's state.
  • Mockito's Role: Mockito is optional here, but it's a great tool to reduce boilerplate when mocking interfaces instead of writing concrete mock classes.

内容的提问来源于stack exchange,提问作者ip696

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:52:51