Dart 中的模拟 http.Client 给出异常

Posted

技术标签:

【中文标题】Dart 中的模拟 http.Client 给出异常【英文标题】:Mock http.Client in Dart gives exception 【发布时间】:2021-09-04 23:13:59 【问题描述】:

我在测试发出 http 请求的类时遇到问题。 我想模拟客户端,以便每次客户端发出请求时,我都可以用模拟响应来回答。 目前我的代码如下所示:

  final fn = MockClientHandler;
  final client = MockClient(fn as Future<Response> Function(Request));

  when(client.get(url)).thenAnswer((realInvocation) async =>
    http.Response('"userId": 1, "id": 2, "title": "mock"', 200));

但是,当我运行测试时,出现以下异常: type '_FunctionType' is not a subtype of type '(Request) =&gt; Future&lt;Response&gt;' in type cast test/data_retrieval/sources/fitbit_test.dart 26:32 main

根据 Flutter/Dart Mockito 应该这样使用:

 final client = MockClient();

  // Use Mockito to return a successful response when it calls the
  // provided http.Client.
  when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1')))
      .thenAnswer((_) async => http.Response('"userId": 1, "id": 2, "title":"mock"', 200));

在示例中,客户端是在没有参数的情况下模拟的,但我想这已经改变了,因为 MockClient 的文档现在也接受了参数。 我不知道为什么会发生此异常,并且在 Internet 上找不到任何内容,所以我想知道这里是否有人知道为什么会发生此异常。

【问题讨论】:

我怀疑问题出在final fn = MockClientHandler;,后来你又做了fn as Future&lt;Response&gt; Function(Request)MockClientHandler 是什么?听起来它是 typedef(这将使其成为 type)而不是 Function 的实例,这会导致强制转换失败。 但是当我不添加演员表时,它会出现编译错误:The argument type 'Type' can't be assigned to the parameter type 'Future&lt;Response&gt; Function(Request)'. 你能帮我看看演员表应该是什么样子吗? 你没有抓住重点。 final fn = MockClientHandler; 出了什么问题。 (这最终是一个无用的任务。之后你可以用fn 做任何有意义的事情。)再一次:MockClientHandler 是什么?目前尚不清楚您对 fn 的期望是什么。 啊,MockClientMockClientHandlerpackage:http 的测试库提供。正如我所怀疑的,您需要提供一个实际的功能。 【参考方案1】:

package:httpMockClient 有点用词不当。这不是真正的模拟(当然与package:mockitoMock无关);它更像是一个 stub(或者可以说是假的):它有一个旨在模拟普通 http.Client 对象的实现。

注意Flutter的Mockito examples使用package:mockito创建了一个MockClient对象,但是这与package:http本身提供的MockClient类无关

final fn = MockClientHandler;
final client = MockClient(fn as Future<Response> Function(Request));

package:httpMockClient 期望MockClientHandlerinstance 作为参数,但您正试图传递MockClientHandler type 本身。你应该提供一个实际的函数(同样,因为MockClient 有一个实际的实现)。

换句话说,如果你想使用package:httpMockClient,那么你应该这样做:

Future<Response> requestHandler(Request request) async 
   return http.Response('"userId": 1, "id": 2, "title": "mock"', 200));


final client = MockClient(requestHandler);

或者如果你想使用package:mockito,你需要关注https://flutter.dev/docs/cookbook/testing/unit/mocking完全生成一个基于Mockito的MockClient类。

【讨论】:

for mockito: ^5.0.17 ,给出此错误 The function 'MockClient' is not defined. @B.shruti 您是否按照说明生成模拟类? 遵循docs.flutter.dev/cookbook/testing/unit/mocking中建议的每一个步骤

以上是关于Dart 中的模拟 http.Client 给出异常的主要内容,如果未能解决你的问题,请参考以下文章

收到推送通知但未显示(Flutter / Dart)

NOIP模拟赛异象石

Dart/Flutter POST 请求和流响应

如何在 dart 中实现适用于移动设备和 Web 的 http 客户端?

如何从 dart 中的属性名称获取属性值(dart 中的 html 属性中的 _EVENTVALIDATION)?

使用 Apache Http Client 4 对比特币钱包的简单 JSON-RPC 调用给出“响应失败”