Flutter模拟HTTP请求插件fake_http_client的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter模拟HTTP请求插件fake_http_client的使用

fake_http_client 是一个用于伪造 Dart/Flutter HttpClient 响应的包。它在集成测试中非常有用,也可以在应用程序开发期间与不稳定的后端一起使用时提供很大帮助。

示例

以下示例强制所有 HTTP 请求返回成功的空响应(200 状态码),且不会执行实际的 HTTP 请求。

import 'package:http/http.dart' as http;
import 'package:fake_http_client/fake_http_client.dart';
import 'package:test/test.dart';

class _EmptyResponseHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(_) => FakeHttpClient(
        // 默认伪造的响应是一个空的 200。
        (request, client) => FakeHttpResponse(),
      );
}

void main() {
  group('HttpClient', () {
    setUp(() {
      // 覆盖所有的 HttpClient 实例。
      HttpOverrides.global = _EmptyResponseHttpOverrides();
    });

    test('returns faked OK empty response for non-existing website', () async {
      // 这实际上是 [FakeHttpClient] 的一个实例。
      final client = HttpClient();
      final request = await client.getUrl(Uri.parse('https://non-existing-site.com'));
      final response = await request.close();

      expect(response.statusCode, HttpStatus.ok);
      expect(response.contentLength, 0);
    });
  });
}

完整示例Demo

下面的代码演示了如何根据不同的URL返回不同的伪造数据:

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:fake_http_client/fake_http_client.dart';

// 自定义的 HttpOverrides 类,用于覆盖默认的 HttpClient 行为。
class _FakeDataHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(_) => FakeHttpClient(
        (request, client) {
          final url = request.uri.toString();

          // 根据 URL 返回不同的伪造响应。
          if (url.contains('non-existing-site')) {
            return FakeHttpResponse(
              body: 'Hey!',
            );
          } else {
            return FakeHttpResponse(
              statusCode: HttpStatus.unauthorized,
              body: 'Sorry, please sign in!',
            );
          }
        },
      );
}

void main() {
  // 使用自定义的 HttpOverrides 运行一段异步代码。
  HttpOverrides.runWithHttpOverrides(
    () async {
      final client = HttpClient();

      // 测试用的 URL 列表。
      final demoUrls = ['https://non-existing-site.com', 'https://foo.com'];

      for (final demoUrl in demoUrls) {
        final request = await client.getUrl(Uri.parse(demoUrl));
        final response = await request.close();
        final responseStatus = response.statusCode;
        final responseBody = await _readResponseBody(response);

        // 打印出每个 URL 对应的状态码和响应体。
        stdout.writeln(
          "'$demoUrl' - $responseStatus - $responseBody",
        );
      }
    },
    _FakeDataHttpOverrides(),
  );
}

// 辅助函数:读取 HttpClientResponse 并将其转换为字符串。
Future<String> _readResponseBody(HttpClientResponse response) {
  final completer = Completer<String>();
  final contents = StringBuffer();

  response.transform(utf8.decoder).listen(
        contents.write,
        onDone: () => completer.complete(contents.toString()),
      );

  return completer.future;
}

关键点说明

  • _FakeDataHttpOverrides 类继承自 HttpOverrides 并重写了 createHttpClient 方法,以返回一个 FakeHttpClient 实例。在这个实例中,我们可以根据传入的请求对象动态地创建不同的 FakeHttpResponse
  • main 函数 中使用了 HttpOverrides.runWithHttpOverrides 方法来确保我们自定义的 HttpOverrides 只在特定的代码块内生效。
  • _readResponseBody 函数用于将 HttpClientResponse 对象转换为字符串格式的内容,方便后续处理或断言。

通过这种方式,开发者可以在不依赖真实网络的情况下测试他们的应用程序逻辑,或者在开发早期阶段模拟不稳定后端的行为。


更多关于Flutter模拟HTTP请求插件fake_http_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter模拟HTTP请求插件fake_http_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用fake_http_client插件来模拟HTTP请求的示例代码。这个插件允许你在开发过程中拦截和模拟HTTP请求,而不需要依赖实际的服务器。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加fake_http_client依赖:

dependencies:
  flutter:
    sdk: flutter
  fake_http_client: ^0.5.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 配置FakeHttpClient

在你的应用初始化时,配置FakeHttpClient。通常,这会在你的主入口文件(如main.dart)中进行。

import 'package:flutter/material.dart';
import 'package:fake_http_client/fake_http_client.dart';
import 'package:http/http.dart' as http;

void main() {
  // 初始化FakeHttpClient
  FakeHttpClient.initialize();

  // 添加模拟的HTTP请求
  FakeHttpClient.addResponse(
    uri: Uri.parse('https://api.example.com/data'),
    method: 'GET',
    response: http.Response(
      body: '{"key": "value"}',
      statusCode: 200,
      headers: {'Content-Type': 'application/json'},
    ),
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fake HTTP Client Demo'),
        ),
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

3. 使用FakeHttpClient进行HTTP请求

在你的业务逻辑中使用http.Client进行请求,它将被FakeHttpClient拦截并返回你配置的模拟响应。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  String responseText = '';

  void fetchData() async {
    final client = http.Client();
    final response = await client.get(Uri.parse('https://api.example.com/data'));

    // 确保释放资源
    response.close();
    client.close();

    setState(() {
      responseText = response.body;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Response:'),
        Text(responseText),
        ElevatedButton(
          onPressed: fetchData,
          child: Text('Fetch Data'),
        ),
      ],
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用。当你点击按钮触发fetchData方法时,它将发起一个HTTP请求,但由于我们配置了FakeHttpClient,这个请求将被拦截,并返回我们在初始化时配置的模拟响应。

总结

通过上面的步骤,你已经成功地在Flutter项目中使用了fake_http_client插件来模拟HTTP请求。这对于开发过程中的单元测试、调试和模拟后端API非常有用。请确保在发布应用之前移除或禁用这些模拟配置。

回到顶部