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

PendingIntent单元测试:如何为指定函数编写测试用例?

为NavDeepLink启动逻辑编写单元测试用例

核心测试点

这段代码的核心是通过NavDeepLinkBuilder构建跳转至UserActivity的PendingIntent,并调用上下文启动它。我们需要验证以下几点:

  • NavDeepLinkBuilder的配置方法是否按预期调用
  • 上下文的startIntentSender是否被正确触发
  • 异常场景下的错误处理逻辑是否生效

依赖准备

确保测试依赖中包含Mockito(用于模拟Android框架类):

testImplementation "org.mockito:mockito-core:5.6.0"
testImplementation "org.mockito:mockito-inline:5.6.0" // 用于mock静态方法和final类

测试用例示例

1. 测试正常流程:验证NavDeepLink配置与启动逻辑

假设你把目标代码封装到了YourClass.launchUserActivity(Context)方法中,测试代码如下:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import android.content.Context;
import android.content.IntentSender;
import android.app.PendingIntent;
import androidx.navigation.NavDeepLinkBuilder;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class NavigationTest {

    @Mock
    private Context mockContext;
    @Mock
    private PendingIntent mockPendingIntent;
    @Mock
    private IntentSender mockIntentSender;

    @Test
    public void launchUserActivity_ShouldConfigureDeepLinkAndStartIntent() throws Exception {
        // 模拟NavDeepLinkBuilder的链式调用
        try (var mockedBuilder = mockStatic(NavDeepLinkBuilder.class)) {
            NavDeepLinkBuilder mockBuilder = mock(NavDeepLinkBuilder.class);
            // 构造链式调用的返回值,保证调用链完整
            mockedBuilder.when(() -> new NavDeepLinkBuilder(mockContext)).thenReturn(mockBuilder);
            when(mockBuilder.setGraph(eq(R.navigation.flow_nav_graph))).thenReturn(mockBuilder);
            when(mockBuilder.setDestination(eq(R.id.UserActicity))).thenReturn(mockBuilder);
            when(mockBuilder.setComponentName(eq(UserActivity.class))).thenReturn(mockBuilder);
            when(mockBuilder.createPendingIntent()).thenReturn(mockPendingIntent);
            // 模拟PendingIntent返回IntentSender
            when(mockPendingIntent.getIntentSender()).thenReturn(mockIntentSender);

            // 执行目标方法
            YourClass.launchUserActivity(mockContext);

            // 验证NavDeepLinkBuilder的配置是否完全符合预期
            mockedBuilder.verify(() -> new NavDeepLinkBuilder(mockContext));
            verify(mockBuilder).setGraph(R.navigation.flow_nav_graph);
            verify(mockBuilder).setDestination(R.id.UserActicity);
            verify(mockBuilder).setComponentName(UserActivity.class);
            verify(mockBuilder).createPendingIntent();

            // 验证上下文是否正确调用了startIntentSender,参数匹配
            verify(mockContext).startIntentSender(
                eq(mockIntentSender),
                eq(null),
                eq(0),
                eq(0),
                eq(0)
            );
        }
    }
}

2. 测试异常场景:验证异常时的栈轨迹打印

@Test
public void launchUserActivity_WhenStartIntentThrowsException_ShouldPrintStackTrace() throws Exception {
    try (var mockedBuilder = mockStatic(NavDeepLinkBuilder.class)) {
        NavDeepLinkBuilder mockBuilder = mock(NavDeepLinkBuilder.class);
        mockedBuilder.when(() -> new NavDeepLinkBuilder(mockContext)).thenReturn(mockBuilder);
        when(mockBuilder.setGraph(eq(R.navigation.flow_nav_graph))).thenReturn(mockBuilder);
        when(mockBuilder.setDestination(eq(R.id.UserActicity))).thenReturn(mockBuilder);
        when(mockBuilder.setComponentName(eq(UserActivity.class))).thenReturn(mockBuilder);
        when(mockBuilder.createPendingIntent()).thenReturn(mockPendingIntent);
        when(mockPendingIntent.getIntentSender()).thenReturn(mockIntentSender);

        // 模拟startIntentSender抛出异常
        Exception testException = new Exception("Test exception");
        doThrow(testException).when(mockContext).startIntentSender(
            eq(mockIntentSender),
            eq(null),
            eq(0),
            eq(0),
            eq(0)
        );

        // 执行目标方法
        YourClass.launchUserActivity(mockContext);

        // 验证异常的printStackTrace方法被调用
        verify(testException).printStackTrace();
    }
}

测试说明

  • 用mockStatic模拟NavDeepLinkBuilder的构造方法,因为它是通过new实例化的
  • 链式调用的模拟需要让每个配置方法返回mock的Builder实例,确保调用链不中断
  • 异常场景中通过doThrow模拟启动逻辑抛出异常,再验证错误处理逻辑是否生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:35:25