Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock http request in flutter integration test?

I'm trying to do so using Mockito, this is my test:

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);
    });
  });
}

And this is my http request code:

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;
}

And here I have the global:

library utgard.globals;

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

http.Client httpClient = http.Client();

However I continue to receive http errors, that indicates to me that the http wasn't replaced by the mock.

like image 289
Felipe Augusto Avatar asked Mar 29 '19 03:03

Felipe Augusto


People also ask

What are the different types of testing in flutter?

There are three types of tests that Flutter supports. A unit test verifies the behavior of a method or class. A widget test verifies the behavior of Flutter widgets without running the app itself. An integration test (also called end-to-end testing or GUI testing) runs the full app.

How do I use Mockito in flutter?

Add the package dependencies To use the mockito package, add it to the pubspec.yaml file along with the flutter_test dependency in the dev_dependencies section. This example also uses the http package, so define that dependency in the dependencies section.

How do I test a fetch function in flutter?

Create a function to test In this example, unit test the fetchAlbum function from the Fetch data from the internet recipe. To test this function, make two changes: Provide an http.Client to the function. This allows providing the correct http.Client depending on the situation. For Flutter and server-side projects, provide an http.IOClient .

How do I get data from the Internet in flutter?

For Flutter and server-side projects, provide an http.IOClient . For Browser apps, provide an http.BrowserClient . For tests, provide a mock http.Client. Use the provided client to fetch data from the internet, rather than the static http.get () method, which is difficult to mock.


2 Answers

The solution I found was to define the mock in test_driver/app.dart and call the runApp function after that:

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());
}
like image 166
Felipe Augusto Avatar answered Nov 15 '22 03:11

Felipe Augusto


Instead of

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

try any and then assert it later

        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');

There's a small chance the call param is not exactly what you mock, so go with any is safer.

like image 31
TruongSinh Avatar answered Nov 15 '22 03:11

TruongSinh