Flutter 类型';空';不是类型为';未来<;回应>';使用Mocktail测试模拟http客户端时
我已经为一个简单的HTTPGET编写了一个测试,使用Mocktail模拟HTTP客户机。当我在测试中调用get方法时,我收到“type'Null'不是type'Future'的子类型” 有人知道为什么会这样吗 以下是测试:Flutter 类型';空';不是类型为';未来<;回应>';使用Mocktail测试模拟http客户端时,flutter,dart,mocking,Flutter,Dart,Mocking,我已经为一个简单的HTTPGET编写了一个测试,使用Mocktail模拟HTTP客户机。当我在测试中调用get方法时,我收到“type'Null'不是type'Future'的子类型” 有人知道为什么会这样吗 以下是测试: class MockHttpClient extends Mock implements http.Client {} void main() { late IdRemoteDataSourceImpl dataSource; late MockHttpClient
class MockHttpClient extends Mock implements http.Client {}
void main() {
late IdRemoteDataSourceImpl dataSource;
late MockHttpClient mockHttpClient;
setUp(
() {
mockHttpClient = MockHttpClient();
dataSource = IdRemoteDataSourceImpl(client: mockHttpClient);
},
);
group('Get id', () {
test(
'when response code is 200',
() async {
final url = Uri.parse('https://api.test.com/');
const tUsername = 'username';
final accountJson = json.decode(
fixture('account.json'),
// ignore: avoid_as
) as Map<String, dynamic>;
final tIdModel = IdModel.fromJson(accountJson);
// arrange
when(() => mockHttpClient.get(url))
.thenAnswer((_) async => http.Response(
fixture('account.json'),
200,
));
// act
final testResult = await dataSource.getId(tUsername);
// assert
// expect(testResult, tIdModel);
},
);
});
}
正在测试的代码:
import 'dart:convert';
import 'package:http/http.dart' as http;
class IdModel {
IdModel({required this.id});
final String id;
factory IdModel.fromJson(Map<String, dynamic> json) {
return IdModel(id: json['id'].toString());
}
}
abstract class IdRemoteDataSource {
Future<IdModel> getId(String username);
}
class IdRemoteDataSourceImpl implements IdRemoteDataSource {
IdRemoteDataSourceImpl({required this.client});
final http.Client client;
@override
Future<IdModel> getId(String username) async {
final url = Uri.parse('https://api.test.com/query?username=$username');
final response = await client.get(url);
// ignore: avoid_as
final responseJson = json.decode(response.body) as Map<String, dynamic>;
return IdModel.fromJson(responseJson);
}
}
导入'dart:convert';
将“package:http/http.dart”导入为http;
类IdModel{
IdModel({required this.id});
最终字符串id;
factory IdModel.fromJson(映射json){
返回IdModel(id:json['id'].toString());
}
}
抽象类IdRemoteDataSource{
未来的getId(字符串用户名);
}
类IdRemoteDataSourceImpl实现IdRemoteDataSource{
IdRemoteDataSourceImpl({必需的this.client});
最终http.Client;
@凌驾
未来getId(字符串用户名)异步{
最终url=Uri.parse('https://api.test.com/query?username=$username');
最终响应=等待client.get(url);
//忽略:避免作为
final responseJson=json.decode(response.body)作为映射;
返回IdModel.fromJson(responseJson);
}
}
错误类型“Null”不是类型“Future”的子类型…
在调用尚未为模拟对象实现的方法或向其传递了不同的参数时发生
在代码中,您向get(…)
方法传递了不同的url参数。Http客户端模拟等待'https://api.test.com/“
但实际上是”https://api.test.com/query?username=$username'
已传递
你有两个选择来解决它
传递到模拟方法:
consttusername='username';
最终url=Uri.parse('https://api.test.com/query?username=$tUsername');
...
//安排
当(()=>mockHttpClient.get(url))时
.thenAnswer(())async=>http.Response(
fixture('account.json'),
200,
),
);
any
matcher(如果您不在乎传递了哪个参数):registerFallbackValue(Uri.parse(“”));
...
当(()=>mockHttpClient.get(any())时
.thenAnswer(())async=>http.Response(
fixture('account.json'),
200,
),
);
太好了,您修复了我的问题,并描述了它失败的原因-非常非常有用:-)我确实发现在使用任何()之前需要将以下内容添加到测试设置中:registerFallbackValue(Uri.parse(');好!!哦,是的,你是对的,类型Uri需要注册FallbackValue。修改我的答案
import 'dart:convert';
import 'package:http/http.dart' as http;
class IdModel {
IdModel({required this.id});
final String id;
factory IdModel.fromJson(Map<String, dynamic> json) {
return IdModel(id: json['id'].toString());
}
}
abstract class IdRemoteDataSource {
Future<IdModel> getId(String username);
}
class IdRemoteDataSourceImpl implements IdRemoteDataSource {
IdRemoteDataSourceImpl({required this.client});
final http.Client client;
@override
Future<IdModel> getId(String username) async {
final url = Uri.parse('https://api.test.com/query?username=$username');
final response = await client.get(url);
// ignore: avoid_as
final responseJson = json.decode(response.body) as Map<String, dynamic>;
return IdModel.fromJson(responseJson);
}
}