如何使用 Mockito 在 Dart 中测试 HTTP SEND?

How to use Mockito to test an HTTP SEND in Dart?

我正在尝试在 dart 中使用 Mockito 来测试我的 API 类.

我创建了一个 Request 以设置 headers(user-agent 等信息)。 然后,我将通过 @GenerateMocks([http.Client]) 注释生成的 MockClient 用于 send 自定义请求。

这就是我变得复杂的地方。 GetPost 请求(通过 client.getclient.post 方法)return 响应,很容易测试。

其实网站上的Mockito测试例子就那么几行:

when(client
          .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1')))
      .thenAnswer((_) async =>
          http.Response('{"userId": 1, "id": 2, "title": "mock"}', 200));

  expect(await fetchAlbum(client), isA<Album>());

我不知道如何在 client.send 的情况下做到这一点,而 return 是 StreamedResponse

到目前为止我收集的点点滴滴无法编译...我什至不知道要争取什么。

  final client = MockClient();

  final http.Request request = RequestBuilder.build("testedRoute", 
    secure: false);
  final String expectedResponse = "some json we (might) get from the server";
  final List<int> expectedBody = utf8.encode(expectedResponse);

  final expectedAnswer = (Invocation invocation) {
  final void Function(List<int>) onData = invocation.positionalArguments[0];
  final void Function() onDone = invocation.namedArguments[#onDone];
  final void Function(Object, [StackTrace]) onError = invocation.namedArguments[#onError];
  final bool cancelOnError = invocation.namedArguments[#cancelOnError];
return new Stream<List<int>>.fromIterable(<List<int>>[expectedBody]).listen(onData, onDone: onDone, onError: onError, cancelOnError: cancelOnError);
  };
  // Use Mockito to return a successful response when it calls the
  // provided http.Client.
  // ***************
  // WHEN
  Future<http.StreamedResponse> streamedResponseFuture = when(
      client.send(request)
  )
 // ***************
 // THEN 
  .thenAnswer(
    // Future<StreamedResponse> Function(Invocation) answer
    (result) async { 
      // return http.StreamedResponse( expectedAnswer, 200);
      return http.StreamedResponse( Stream<List<int>>.fromIterable(<List<int>>[expectedBody]), 200);
    }
           );

final fetchResult = await APIManager().fetchThings();
expect(fetchResult, isNotEmpty);
expect(fetchResult.first, isA<Thing>());

多亏了@Jamesdlin,我才开始工作! 我确实在这里偏离了路线,这是我现在使用的代码:

 test('returns an list of Things if the http call completes successfully', () async {
  var client = testing.MockClient.streaming((request, bodyStream) {
    return bodyStream.bytesToString().then((bodyString) {
      var controller = StreamController<List<int>>(sync: true);
      Future.sync(() {

        final String expectedResponse = "some json we (might) get from the server";
        final List<int> expectedBody = utf8.encode(expectedResponse);
        controller.add(expectedBody);
        controller.close();
      });
      return http.StreamedResponse(controller.stream, 200);
    });
    });
  // Run a send manually to demonstrate what the return is supposed to hold
  client.send(http.Request(HttpMethod.GET.toString(),Uri(path:"my path")))
    .then((value) =>
    value.stream.first.then((value) {
      final thing = utf8.decode(value).toString();
      debugPrint("******************** $thing *****************");
      return thing;
    })
  );
  final fetchThingsResult = await APIManager(client: client).fetchThings();
  expect(fetchThingsResult , isNotEmpty);
  expect(fetchThingsResult .first, isA<Thing>());
});