Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 类型';空';不是类型为';未来<;回应>';使用Mocktail测试模拟http客户端时_Flutter_Dart_Mocking - Fatal编程技术网

Flutter 类型';空';不是类型为';未来<;回应>';使用Mocktail测试模拟http客户端时

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

我已经为一个简单的HTTPGET编写了一个测试,使用Mocktail模拟HTTP客户机。当我在测试中调用get方法时,我收到“type'Null'不是type'Future'的子类型”

有人知道为什么会这样吗

以下是测试:

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'
已传递

你有两个选择来解决它

  • 当(…)将在测试期间通过的url从
    传递到模拟方法:
  • 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);
      }
    }