dart单元测试中的verify调用中没有匹配的调用

f1tvaqid  于 2023-05-11  发布在  其他
关注(0)|答案(1)|浏览(114)

我想测试一个远程服务器请求方法,但我不知道为什么会得到:没有匹配的电话。所有调用:MockClient.send(GEThttps://exampleDomain.test.com/send_email)。
我已经搜索了堆栈溢出,有人使用equatable包来比较对象,但我不知道如何实现这个包或实现http.RequestMockRequest对象的相等性。以下是我的方法:

@override
  Future<void> sendEmail(String email) async {
    if (!EmailValidator.validate(email)) throw InvalidEmailFormatException();
    final requestUrl = baseUri.replace(path: '/account/send_email');
    final request = http.Request(RequestMethod.get.method, requestUrl);
    request.headers.clear();
    request.headers.addAll({"Content-type": "text/plain"});
    request.body = '{"email":"$email"}';
    try {
      final response = await _client.send(request);

      if (response.statusCode != 200) {
        throw HttpException(
            'Response statuse code = ${response.statusCode}, Reason phrase = ${response.reasonPhrase}',
            uri: requestUrl);
      }
      final responseBodyString = await response.stream.bytesToString();
      final reponseJson =
          jsonDecode(responseBodyString) as Map<String, dynamic>;
      final code = reponseJson['code'];
      if (code != 200) {
        throw ServerException(code, uri: requestUrl);
      }
    } on SocketException {
      rethrow;
    } on FormatException {
      rethrow;
    }
  }

下面是我的单元测试:

class MockClient extends Mock implements http.Client {}

class MockResponse extends Mock implements http.StreamedResponse {}

class MockRequest extends Mock with EquatableMixin implements http.Request {}
...
      test('make correct http request', () async {
        final uri = baseUri.replace(path: 'account/send_email');

        final response = MockResponse();
        when(
          () => response.statusCode,
        ).thenReturn(200);

        when(
          () => response.stream,
        ).thenAnswer(
          (_) => http.ByteStream.fromBytes('OK'.codeUnits),
        );

        final request = MockRequest();

        when(
          () => request.method,
        ).thenReturn('GET');

        when(
          () => request.body,
        ).thenReturn('{"email":"$validEmail"}');

        when(
          () => request.headers,
        ).thenReturn({
          'Content-Type': 'text/plain',
        });

        when(
          () => request.url,
        ).thenReturn(uri);

        when(() => client.send(any())).thenAnswer((_) async => response);

        try {
          await sut.sendEmail(validEmail);
        } catch (_) {}
        verify(() => client.send(request)).called(1);
      });
hwamh0ep

hwamh0ep1#

使用meta包,您应该使用@visibleForTesting注解将Mockrequest注入到构造函数中。

final htt.Request? _request;
class Api{
  Api(@visibleForTesting http.Request? request): _request = request;
  @override
  Future<void> sendEmail(String email) async {
    ...
    final request = _request ?? http.Request(RequestMethod.get.method, requestUrl);
    ...
  }
}

然后在测试单元中使用MockRequest注入API类。

test('calls the correct endpoint', () async {
          final email = 'email@email.com';
          when(
            () => mockRequest.url,
          ).thenReturn(baseUri.replace(path: '/account/send_email'));
          when(
            () => mockRequest.method,
          ).thenReturn(RequestMethod.post);
          when(
            () => mockRequest.headers,
          ).thenReturn({'Content-Type': 'text/plain'});
          when(
            () => mockRequest.body,
          ).thenReturn('{"email": "$email"}');
          try {
            await sut.sendEmail(email);
          } catch (e) {}
          verify(
            () => client.send(mockRequest),
          ).called(1);
        });

相关问题