API 통신 기능을 unit test 할 때 실제 API를 호출하여 진행하면 몇 가지 문제가 있다.
- 실제 API를 요청하게 되면 test 성능이 저하될 수 있다.
- 서버의 이상 유무에 따라 응답 값이 달라질 수 있고, 이 경우 테스트가 실패하게 된다.
- 모든 성공, 실패를 테스트하기는 무리가 있다.
위와 같은 이유로 Flutter에서는 Mock 객체를 생성하여 다양한 케이스를 테스트할 수 있고, 이는 annotation과 code generation을 제공하는 mockito 패키지를 이용하여 진행하면 된다.
Example
Mockito Package
https://pub.dev/packages/mockito
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.3.3
mockito: ^5.4.0
Pixabay에서 제공하는 이미지 검색 API 통신을 테스트 해보려고 한다.
1. 테스트 할 메서드 작성
테스트 시 Dio Mock 객체를 받을 수 있도록 파라미터에 Dio를 추가해준다.
Future<List<Photo>> fetch(String query, {Dio? dio}) async {
dio ??= Dio();
final response = await dio.get(
"$baseUrl?key=$key&q=$query&image_type=photo&pretty=true",
);
final hits = response.data["hits"] as List;
return hits.map((e) => Photo.fromJson(e)).toList();
}
2. 테스트 코드 작성
pixabay_api_test.dart
성공 케이스를 테스트할 것이기 때문에 성공 시 데이터를 임의로 정의해준다.
Map<String, dynamic> json = {
"total":8740,
"totalHits":500,
"hits":[
{
"id":2681039,
"pageURL":"https://pixabay.com/photos/phone-wallpaper-watercolor-painting-2681039/",
"type":"photo",
"tags":"phone wallpaper, watercolor, painting",
"previewURL":"https://cdn.pixabay.com/photo/2017/08/25/18/48/watercolor-2681039_150.jpg",
"previewWidth":99,
"previewHeight":150,
"webformatURL":"https://pixabay.com/get/g4294e9afbf2e8811de22692f01d36829bb92a29d6b16bb14907db22b665c939ca1a0dac346e921298c381c365cd5fd4ea928dfa11c2dc8d41ce8f9cf37fd61d6_640.jpg",
"webformatWidth":424,
"webformatHeight":640,
"largeImageURL":"https://pixabay.com/get/g070184928be6f74c342546d1db00d7d4bc3e248539e1bd9157bf7a656ee26fadfcf2285fa298c658245febfd4341aee82d4aba07205b4d02976e741ec40c2694_1280.jpg",
"imageWidth":3264,
"imageHeight":4928,
"imageSize":5021313,
"views":1254783,
"downloads":976006,
"collections":1948,
"likes":1247,
"comments":135,
"user_id":4894494,
"user":"eluela31",
"userImageURL":"https://cdn.pixabay.com/user/2017/04/24/19-55-29-652_250x250.jpg"
},
...
]
};
위와 같이 임의로 성공 시의 데이터를 정의하고 이를 응답 값으로 설정해주는 액션을 취하기 위해 새로운 요청 객체를 생성해줘야하는데, 이 것이 Mock 객체이다.
어노테이션을 통해 Mock 객체를 생성할 수 있고, 나는 Dio를 사용하기 때문에 @GenerateMock([Dio])의 형태로 어노테이션을 사용했다. 이 후 Terminal에 코드 생성 명령어를 입력하면 pixabay_api_test.mock.dart 파일이 생성된다.
@GenerateMocks([Dio])
void main() {}
flutter pub run build_runner build
main method
생성한 MockDio 객체와 mockito 패키지에서 제공하는 when 메서드를 이용하여 성공 조건을 설정해줄 수 있다.
when의 인자로 테스트하려는 요청 함수를 지정하고 when의 반환 클래스인 PostExpectation 클래스의 thenAnswer 메서드로 응답 값을 설정해준다.
마지막으로 verify 메서드를 통해 인자로 지정된 메서드가 호출되었는지 확인한다.
@GenerateMocks([Dio])
void main() {
test("pixabay api test", () async {
final api = PixabayApi();
final dio = MockDio();
when(dio.get(
"${PixabayApi.baseUrl}?key=${PixabayApi.key}&q=iphone&image_type=photo&pretty=true",
)).thenAnswer((_) async => Response(
data: json,
statusCode: 200,
requestOptions: RequestOptions(),
));
final result = await api.fetch("iphone", dio: dio);
expect(result.first.id, 2681039);
verify(dio.get(
"${PixabayApi.baseUrl}?key=${PixabayApi.key}&q=iphone&image_type=photo&pretty=true",
));
});
}
Result
'Flutter' 카테고리의 다른 글
flutter_gen 패키지를 이용하여 asset 사용하기 (0) | 2023.11.27 |
---|---|
Flutter MVVM Architecture (0) | 2023.05.30 |
Flutter InheritedWidget (0) | 2023.04.18 |
뒤늦게 정리하는 Flutter riverpod 개념 (0) | 2023.04.06 |
Debounce와 Throttle (0) | 2023.04.06 |