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

在Android中如何对`Thread.currentThread()`相关逻辑进行单元测试

checkNotMainThread 单元测试方案

核心验证逻辑:需要覆盖两种场景:当前线程为主线程时方法抛出异常,当前线程为子线程时方法执行正常。

方案1:JUnit + Mockito 实现(无Robolectric依赖)

适配纯Java单元测试场景,通过mock主线程相关对象实现校验:

  • 先通过静态mock替换Looper.getMainLooper()的返回值,绑定mock的主线程对象
  • 主线程场景测试:将mock的主线程设置为和当前测试线程一致,调用方法验证是否抛出预期异常
  • 子线程场景测试:让mock的主线程和当前执行测试的线程不一致,在独立子线程中调用方法验证无异常

示例代码:

@RunWith(MockitoJUnitRunner.class)
public class ThreadCheckerTest {
    @Mock
    private Looper mockMainLooper;
    @Mock
    private Thread mockMainThread;

    @Before
    public void initMock() {
        Mockito.mockStatic(Looper.class);
        when(Looper.getMainLooper()).thenReturn(mockMainLooper);
        when(mockMainLooper.getThread()).thenReturn(mockMainThread);
    }

    @Test(expected = IllegalStateException.class)
    public void checkNotMainThread_throw_when_running_on_main_thread() {
        // 模拟当前测试线程就是主线程
        when(mockMainThread.getId()).thenReturn(Thread.currentThread().getId());
        ThreadChecker.checkNotMainThread();
    }

    @Test
    public void checkNotMainThread_pass_when_running_on_work_thread() throws InterruptedException {
        // 模拟主线程id和当前线程id不一致
        when(mockMainThread.getId()).thenReturn(999L);
        CountDownLatch latch = new CountDownLatch(1);
        new Thread(() -> {
            ThreadChecker.checkNotMainThread();
            latch.countDown();
        }).start();
        latch.await(2, TimeUnit.SECONDS);
    }
}

方案2:Robolectric 实现(Android单元测试场景)

如果项目已经接入Robolectric做Android单元测试,可以直接依赖框架的线程模拟能力,不需要额外mock:

  • Robolectric默认测试代码运行在模拟的主线程,直接调用方法即可验证异常场景
  • 子线程场景和方案1一致,单独开子线程调用方法验证即可

示例代码:

@RunWith(RobolectricTestRunner.class)
public class ThreadCheckerTest {
    @Test(expected = IllegalStateException.class)
    public void checkNotMainThread_throw_when_running_on_main_thread() {
        ThreadChecker.checkNotMainThread();
    }

    @Test
    public void checkNotMainThread_pass_when_running_on_work_thread() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        new Thread(() -> {
            ThreadChecker.checkNotMainThread();
            latch.countDown();
        }).start();
        latch.await(2, TimeUnit.SECONDS);
    }
}

注意:如果checkNotMainThread内部是直接对比线程对象而非线程id,mock时需要直接将mockMainThread赋值为当前测试线程对象,不要只修改id属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:36:03