如何在颤振集成测试中模拟 http 请求?

Posted

技术标签:

【中文标题】如何在颤振集成测试中模拟 http 请求?【英文标题】:How to mock http request in flutter integration test? 【发布时间】:2019-08-19 22:54:56 【问题描述】:

我正在尝试使用 Mockito 这样做,这是我的测试:

import 'package:http/http.dart' as http;
import 'package:utgard/globals.dart' as globals;
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';

class MockClient extends Mock implements http.Client 

void main() 
  group('Login flow', () 

    final SerializableFinder loginContinuePasswordButton =
        find.byValueKey('login_continue_password_button');

    FlutterDriver driver;

    setUpAll(() async 
      driver = await FlutterDriver.connect();
    );

    tearDownAll(() async 
      if (driver != null) 
        //await driver.close();
      
    );


    test('login with correct password', () async 
      final client = MockClient();

      when(client.post('http://wwww.google.com'))
          .thenAnswer((_) async => http.Response('"title": "Test"', 200));

      globals.httpClient = client;

      await driver.enterText('000000');
      await driver.tap(loginContinuePasswordButton);
    );
  );

这是我的 http 请求代码:

Future<Map<String, dynamic>> post(
  RequestType requestType,
  Map<String, dynamic> body,
) async 
  final http.Response response =
      await globals.httpClient.post('http://wwww.google.com');

  print(response);

  final Map<String, dynamic> finalResponse = buildResponse(response);

  _managerErrors(finalResponse);

  return finalResponse;

这里我有全局:

library utgard.globals;

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

http.Client httpClient = http.Client();

但是我继续收到 http 错误,这表明 http 没有被 mock 替换。

【问题讨论】:

我在下面给出了一个建议答案,但这有点远,因为我没有`final SerializableFinder loginContinuePasswordButton = find.byValueKey('login_continue_password_button');`的代码。问题出在那儿的可能性很小。 嗨 Felipe,你能找到一种方法来模拟 Flutter 集成测试中的依赖关系吗?使用DataHandler 提到的here 怎么样? 【参考方案1】:

代替

      when(client.post('http://wwww.google.com'))
          .thenAnswer((_) async => http.Response('"title": "Test"', 200));

尝试any,稍后再断言

        when(
          mockHttpClient.send(any),
        ).thenAnswer((_) async => http.Response('"title": "Test"', 200));
// ...
        final String capt = verify(client.send(captureAny)).captured;
        expect(capt, 'http://wwww.google.com');

调用参数不太可能与您模拟的完全不一样,因此使用any 更安全。

【讨论】:

【参考方案2】:

我找到的解决方案是在 test_driver/app.dart 中定义模拟,然后调用 runApp 函数:

import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:utgard/business/config/globals.dart';
import 'package:utgard/main.dart' as app;

class MockClient extends Mock implements http.Client 

void main() 
  enableFlutterDriverExtension();

  final MockClient client = MockClient();
  // make your mocks here
  httpClient = client;

  runApp(app.MyApp());

【讨论】:

以上是关于如何在颤振集成测试中模拟 http 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何在集成测试中重置 Firestore 模拟器

颤振从单元\小部件测试调用http请求而不进行模拟

使用颤振集成驱动程序在测试代码中捕获异常

如何在集成测试中模拟 BLoC

集成测试颤振包与许多其他包不兼容

用于集成测试的 Java 测试项目