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

Flutter自定义页面Widget测试触发HttpClient警告如何解决?

错误原因

Flutter Widget测试默认会拦截所有HTTP请求,不允许真实网络请求发出,你的代码里有两个场景会触发HTTP请求导致告警:

  • 老师头像存在网络地址时,NetworkImage组件会发起请求加载图片
  • 页面build方法中Future.wait依赖的_teacherData、_campusData等异步接口底层使用了HttpClient发起网络请求

解决步骤

1. 模拟页面异步数据源

不要让页面在测试中发起真实接口请求,直接返回预设的测试数据,可根据你的情况二选一:

  • 优先方案:调整页面代码,把四个异步请求的依赖改成可注入参数,测试时直接传入写死的mock数据即可,不需要修改业务逻辑
  • 兼容方案:如果不想改动现有页面代码,可使用mock工具拦截对应接口的调用,返回预设的测试数据,包含你要验证的老师姓名、校区地址等字段即可。

2. 处理NetworkImage的请求

有两种方案避免头像加载触发网络请求:

  • 测试时给teacherData['user']['img_url']传空值,让页面自动走本地占位图逻辑,不会触发网络请求
  • 如果需要测试头像正常加载的场景,可使用HttpOverrides全局拦截测试中的图片请求,返回模拟响应,示例代码如下:
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';

void main() {
  setUp(() {
    // 全局拦截所有HTTP请求
    HttpOverrides.global = _MockHttpOverrides();
  });

  // 这里写你的测试用例
}

class _MockHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return super.createHttpClient(context)
      ..getUrl = (Uri uri) async => _MockHttpClientRequest()
      ..get = (uri, path) async => _MockHttpClientRequest();
  }
}

class _MockHttpClientRequest extends Fake implements HttpClientRequest {
  @override
  Future<HttpClientResponse> close() async => _MockHttpClientResponse();
}

class _MockHttpClientResponse extends Fake implements HttpClientResponse {
  @override
  int get statusCode => HttpStatus.ok;
  @override
  Stream<List<int>> get body => Stream.value(<int>[]);
  @override
  int get contentLength => 0;
  @override
  HttpHeaders get headers => HttpHeaders();
}

3. 基础测试用例示例

测试Text组件是否正常显示的参考代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
// 导入你的BookingDetails页面
import 'package:your_app/booking_details.dart';

void main() {
  setUp(() {
    HttpOverrides.global = _MockHttpOverrides();
  });

  testWidgets('验证BookingDetails页面文本显示正常', (tester) async {
    // 构造测试需要的mock数据
    final mockBooking = {'cancelled_by_inst': false, 'teacher_id': '1001'};
    final mockTeacherData = {
      'user': {
        'first_name': '李',
        'last_name': '明',
        'img_url': ''
      }
    };
    final mockCampusData = [
      {'address_line1': '学院路15号', 'suburb': '海淀区', 'state': '北京', 'postcode': '100083'}
    ];

    // 加载页面,必须套MaterialApp提供必要的主题、路由等依赖
    await tester.pumpWidget(
      MaterialApp(
        home: BookingDetails(mockBooking),
      ),
    );

    // 等待Future加载完成、页面渲染结束
    await tester.pumpAndSettle();

    // 验证目标Text组件是否存在
    expect(find.text('李'), findsOneWidget);
    expect(find.text('明'), findsOneWidget);
    expect(find.text('学院路15号, 海淀区, 北京 100083 '), findsOneWidget);
  });
}

// 上面的_MockHttpOverrides类写在这里即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:39:03