首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在用Mocktail测试模拟的http客户端时,'Null‘不是'Future<Response>’类型的子类型

在用Mocktail测试模拟的http客户端时,'Null‘不是'Future<Response>’类型的子类型
EN

Stack Overflow用户
提问于 2021-06-09 06:59:05
回答 1查看 5.6K关注 0票数 8

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

有人知道为什么会这样吗?

下面是一个测试:

代码语言:javascript
运行
复制
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);
      },
    );
  });
}

当运行以下行时会发生此错误:

代码语言:javascript
运行
复制
final testResult = await dataSource.getId(tUsername);

正在测试的代码:

代码语言:javascript
运行
复制
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);
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-09 07:26:05

当您调用未为模拟对象实现的方法或传递给它的不同参数时,会发生错误type 'Null' is not a subtype of type 'Future'...

在您的代码中,您向get(...)方法传递了不同的url参数。Http客户端模拟等待'https://api.test.com/',但实际上已经传递了'https://api.test.com/query?username=$username'

你有两个选择来解决它。

  1. when(...)传递相同的url到模拟方法,该方法将在测试期间通过:

代码语言:javascript
运行
复制
const tUsername = 'username';
final url = Uri.parse('https://api.test.com/query?username=$tUsername');
...
// arrange
when(() => mockHttpClient.get(url))
  .thenAnswer((_) async => http.Response(
      fixture('account.json'),
      200,
  ),
);

  1. 使用any matcher (如果您不关心传递哪个参数):

代码语言:javascript
运行
复制
registerFallbackValue(Uri.parse(''));
...
when(() => mockHttpClient.get(any()))
  .thenAnswer((_) async => http.Response(
      fixture('account.json'),
      200,
  ),
);
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67899067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档