Back to Repositories

Testing Local URI Stream Fetching Implementation in Glide

This test suite validates the StreamLocalUriFetcher component in Glide, focusing on handling local URI resources and input stream processing. It verifies proper stream loading behavior and error handling when accessing local files through ContentResolver.

Test Coverage Overview

The test suite provides comprehensive coverage of the StreamLocalUriFetcher class, focusing on local URI resource handling.

Key areas tested include:
  • Successful input stream retrieval from local URIs
  • Proper error handling for null input streams
  • Integration with Android’s ContentResolver
  • Callback behavior for both success and failure scenarios

Implementation Analysis

The testing approach utilizes Robolectric for Android environment simulation and Mockito for dependency mocking.

Key implementation patterns include:
  • Shadow classes for ContentResolver behavior simulation
  • Mock callbacks to verify asynchronous operations
  • Priority handling verification
  • URI parsing and resource access testing

Technical Details

Testing infrastructure includes:
  • JUnit 4 test framework
  • Robolectric test runner with SDK configuration
  • Mockito for mocking and verification
  • Custom ContentResolverShadow for resource simulation
  • ApplicationProvider for context access

Best Practices Demonstrated

The test suite exemplifies several testing best practices for Android components.

Notable practices include:
  • Proper test setup and initialization using @Before
  • Isolated test cases with specific assertions
  • Effective use of mocking for external dependencies
  • Clear separation of success and failure scenarios
  • Comprehensive error condition coverage

bumptech/glide

library/test/src/test/java/com/bumptech/glide/load/data/resource/StreamLocalUriFetcherTest.java

            
package com.bumptech.glide.load.data.resource;

import static com.bumptech.glide.RobolectricConstants.ROBOLECTRIC_SDK;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.verify;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.data.StreamLocalUriFetcher;
import com.bumptech.glide.tests.ContentResolverShadow;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;

@RunWith(RobolectricTestRunner.class)
@Config(
    sdk = ROBOLECTRIC_SDK,
    shadows = {ContentResolverShadow.class})
public class StreamLocalUriFetcherTest {
  @Mock private DataFetcher.DataCallback<InputStream> callback;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testLoadResource_returnsInputStream() throws Exception {
    Context context = ApplicationProvider.getApplicationContext();
    Uri uri = Uri.parse("file://nothing");

    ContentResolver contentResolver = context.getContentResolver();
    ContentResolverShadow shadow = Shadow.extract(contentResolver);
    shadow.registerInputStream(uri, new ByteArrayInputStream(new byte[0]));

    StreamLocalUriFetcher fetcher = new StreamLocalUriFetcher(context.getContentResolver(), uri);
    fetcher.loadData(Priority.NORMAL, callback);
    verify(callback).onDataReady(ArgumentMatchers.<InputStream>isNotNull());
  }

  @Test
  public void testLoadResource_withNullInputStream_callsLoadFailed() {
    Context context = ApplicationProvider.getApplicationContext();
    Uri uri = Uri.parse("file://nothing");

    ContentResolver contentResolver = context.getContentResolver();
    ContentResolverShadow shadow = Shadow.extract(contentResolver);

    shadow.registerInputStream(uri, null /*inputStream*/);

    StreamLocalUriFetcher fetcher = new StreamLocalUriFetcher(context.getContentResolver(), uri);
    fetcher.loadData(Priority.LOW, callback);

    verify(callback).onLoadFailed(isA(FileNotFoundException.class));
  }
}