如何用Mockito对Flutter中Dio实现的登录认证POST请求做单元测试?
Flutter Dio登录认证请求单元测试Mock示例
问题场景
使用Dio实现Flutter登录认证POST请求后,编写单元测试时,通过Mockito Mock Dio的post方法时,不清楚该返回何种响应,无法完成Mock操作,需要针对该场景的详细单元测试示例。
登录认证请求代码
Future<String?> authentication(String mobileNumber, String password, Dio dio) async { dynamic data = { "username": mobileNumber, "password": password, "grant_type": "password", "client_id": "client_id" }; try { final response = await dio.post(baseurl, // 注:原代码中_dio应为传入的dio参数 data: data, options: Options(headers: { "Content-Type": "application/x-www-form-urlencoded" })); if (response.statusCode == 200) { accessToken = response.data["access_token"]; refreshToken = response.data["refresh_token"]; Fluttertoast.showToast(msg: "Successfully Logged in"); return accessToken; } } on DioError catch (e) { Fluttertoast.showToast(msg: "Something went wrong"); return e.toString(); } return accessToken; }
完整单元测试实现
确保已添加依赖:mockito、flutter_test,并通过flutter pub run build_runner build生成Mock类。
成功场景测试
import 'package:dio/dio.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; // 通过mockito生成的MockDio类 class MockDio extends Mock implements Dio {} void main() { late MockDio mockDio; late YourAuthService service; // 替换为你的认证服务类 setUp(() { mockDio = MockDio(); service = YourAuthService(); // 初始化你的服务类 }); test("认证成功时返回token", () async { // 构造Dio成功响应 final mockResponse = Response( requestOptions: RequestOptions(path: Apiservices().baseurl), statusCode: 200, data: { "access_token": "test_token_123", "refresh_token": "refresh_token_456" }, ); // Mock Dio的post方法,匹配请求参数 when(mockDio.post( Apiservices().baseurl, data: { "username": "username", "password": "password", "grant_type": "password", "client_id": "client_id" }, options: anyNamed('options'), )).thenAnswer((_) async => mockResponse); // 执行测试 final result = await service.authentication("username", "password", mockDio); // 验证结果 expect(result, "test_token_123"); expect(result, isA<String>()); // 验证Dio的post方法被调用一次 verify(mockDio.post( Apiservices().baseurl, data: anyNamed('data'), options: anyNamed('options'), )).called(1); }); }
错误场景测试(Dio请求失败)
test("认证失败时返回错误信息", () async { // 构造Dio错误 final mockDioError = DioError( requestOptions: RequestOptions(path: Apiservices().baseurl), response: Response( requestOptions: RequestOptions(path: Apiservices().baseurl), statusCode: 401, data: {"error": "Invalid credentials"}, ), type: DioErrorType.response, ); // Mock Dio的post方法抛出错误 when(mockDio.post( Apiservices().baseurl, data: anyNamed('data'), options: anyNamed('options'), )).thenThrow(mockDioError); // 执行测试 final result = await service.authentication("wrong_user", "wrong_pass", mockDio); // 验证结果 expect(result, mockDioError.toString()); verify(mockDio.post( Apiservices().baseurl, data: anyNamed('data'), options: anyNamed('options'), )).called(1); });
关键说明
- 构造Dio Response:必须实例化
Response类,至少指定requestOptions(必填项,传入请求路径)、statusCode和data参数。 - Mock匹配规则:若需严格验证请求参数,可在
when中明确指定匹配条件;无需精确匹配时,用anyNamed('data')等模糊匹配。 - Mock类生成:必须通过
build_runner工具生成MockDio类,否则会出现未定义类的错误。
内容的提问来源于stack exchange,提问作者Rafi Muhd
相关产品推荐
相关产品推荐

