본문 바로가기

개발하자

플러터 통합 테스트에서 http 요청을 모의 실험하는 방법은 무엇인가요?

반응형

플러터 통합 테스트에서 http 요청을 모의 실험하는 방법은 무엇인가요?

모키토를 사용해서 그렇게 하려고 합니다. 이것이 제 시험입니다:

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가 모의로 대체되지 않았다는 것을 나타낸다.




대신에

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

나중에 그것을 주장하다

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

호출 매개 변수가 당신이 조롱하는 것과 정확히 일치하지 않을 가능성이 작으므로 사용하는 것이 더 안전합니다.




제가 찾은 해결책은 모의 입력을 정의하고 그 이후에 함수를 호출하는 것이었습니다:

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



테스트 중인 코드가 보이지 않지만 다음과 같은 요청을 할 가능성은 거의 없습니다:

client.post('http://wwww.google.com')

어쨌든 모의 json 파일을 사용하는 것이 좋은 관행이며, 그런 모의 파일이 바뀔 때마다 요청을 변경하고 싶지 않을 것이다.

모키토 대신 사용하는 것을 추천합니다.

이를 통해 다음과 같은 방법으로 모든 통화를 시뮬레이션할 수 있습니다:

// Simulate any GET :
mockHttpClient.get(any()))

// Simulate any POST :
mockHttpClient.post(any()))

다음은 완전한 솔루션입니다:

class MockClient extends Mock implements http.Client {}
class FakeUri extends Fake implements Uri {}

void main() {

  setUp(() {
    registerFallbackValue(FakeUri()); // Required by Mocktail
  });
  tearDown(() {});

  MockHttpClient mockHttpClient = MockHttpClient();
  group('Login flow', () {
    test('login with correct password', () async {
      when(() => mockHttpClient.get(any())).thenAnswer(((_) async {
        return Response(mockWeatherResponse, 200);
      }));
    
    // Call the functions you need to test here

    }
  }
}



플러터 통합 테스트에는 서비스(HTTP 통화 포함)를 모의시험하는 것이 있다. 나는 이것을 충분히 강조할 수 없다: 그것은 그렇다.

(위젯 테스트나 단위 테스트를 작성하는 경우 조롱은 간단합니다. 당신은 직접 조롱을 쓰거나 모조 꼬리나 모조끼토를 사용할 수 있다.)

이 답변의 목적을 위해 사용 중인 경우, 즉 시뮬레이터 또는 물리적 장치에서 테스트가 실행 중인 경우 통합 테스트를 수행하게 됩니다. 이 경우 앱 코드와 테스트 코드가 서로 다른 격리된 상태에서 실행되므로 테스트 코드에서 수행하는 작업이 앱 코드에서 발생하는 작업에 영향을 줄 수 없으며 그 반대도 마찬가지입니다. 그들은 서로 벽으로 둘러싸여 있다.

과거에는 DataHandler를 사용하여 설명한 대로 테스트와 앱 사이에 메시지를 주고받을 수 있었습니다. 이제는 더 이상 쓸모가 없으며 패키지에 해당하는 것은 없습니다. 를 참조하십시오. 현재는 열려 있습니다.

플러터 팀의 통합 테스트 개념은 최종 사용자가 앱을 사용할 때 수행하는 작업을 정확하게 반영해야 한다는 것입니다. 에르고, 조롱해서는 안 돼. 위젯/유닛 테스트에서는 모든 HTTP 요청이 스터브(HTTP 400 반환)되지만 통합 테스트에서는 정상적으로 작동합니다.

통합 테스트에서 반복성이 필요한 경우 플러터 외부의 환경 수준에서 파악해야 합니다.


반응형