颤振/Mockito。使用 mockito 测试 API 提供者,api 标头有问题

Ste*_*eed 2 mockito dart flutter

我想用 mockito 插件测试我的提供者,但有一个问题,正如我对标题的理解。

当我执行打印(响应)时显示为

如果我从 API 中删除标题

headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'Authorization': 'Bearer $token',
      },
Run Code Online (Sandbox Code Playgroud)

测试工作正常,但带有标题:

NoSuchMethodError: The getter 'statusCode' was called on null.
Receiver: null
Tried calling: statusCode
dart:core                                                   Object.noSuchMethod
package:mba/resources/providers/post_provider.dart 38:20  PostProvider.fetchPosts
===== asynchronous gap ===========================
dart:async                                                  _AsyncAwaitCompleter.completeError
package:mba/resources/providers/post_provider.dart        PostProvider.fetchPosts
===== asynchronous gap ===========================
dart:async                                                  _asyncThenWrapperHelper
package:mba/resources/providers/post_provider.dart        PostProvider.fetchPosts
test/resources/providers/post_provider_test.dart 46:39    main.<fn>.<fn>
Run Code Online (Sandbox Code Playgroud)

提供者:

import 'package:http/http.dart' as http;

import 'package:mba/env.dart';
import 'package:mba/core/models/post_model.dart';


class PostProvider {
  final http.Client client;

  final String _api = API;
  // Map<String, List<Post>> _postsList = Map();

  PostProvider(this.client);

  Future<Map<String, List<Post>>> fetchPosts(String token) async {
    final response = await client.get(
      '${_api}posts',
      headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'Authorization': 'Bearer $token',
      },
    );

    print('-------------');
    print(response);
    print(response.statusCode);
    print(response.body);

    //todo: decode and mapping
    if (response.statusCode == 200) {
      return Map();
    } else {
      throw 'xxxx';
    }
  }
Run Code Online (Sandbox Code Playgroud)

测试文件:

import 'dart:io';
import 'package:mba/resources/providers/post_provider.dart';
import 'package:mockito/mockito.dart';
import 'package:http/http.dart' as http;

import 'package:flutter_test/flutter_test.dart';
import 'package:matcher/matcher.dart';


class MockClient extends Mock implements http.Client {}

void main() {
  String fixture(String name) =>
      File('test/fixtures/posts/$name.json').readAsStringSync();

  MockClient mockClient;
  PostProvider dataSource;

  setUp(() {
    mockClient = MockClient();
    dataSource = PostProvider(mockClient);
  });

  group('searchVideos', () {
    test(
      'returns YoutubeSearchResult when the call completes successfully',
      () async {
        when(
          mockClient.get(
            argThat(
              startsWith('http://localhost:55005/api'),
            ),
          ),
        ).thenAnswer(
          (_) async => http.Response(
                fixture('posts'),
                200,
                headers: {'content-type': 'application/json; charset=utf-8'},
              ),
        );

        var result = await dataSource.fetchPosts('resocoder');
        print(result);

      },
    );
  });


}

Run Code Online (Sandbox Code Playgroud)

Mul*_*dec 5

when当且仅当所有 argsmockClient.get()与您指定的匹配时,Mockito 才会响应您的句子。

在您的情况下,您指定了一个 URL,仅此而已。由于您的代码使用 URL 并且标头 mockito 将不匹配并且不会执行您的thenAnswer.

在您的when句子中,您必须指定 headers 参数以匹配您测试的代码

        when(
          mockClient.get(
            argThat(
              startsWith('http://localhost:55005/api'),
            ),
            headers: anyNamed('headers'), // Add this line
          ),
        ).thenAnswer(...);
Run Code Online (Sandbox Code Playgroud)

在这里,anyNamed('headers')将匹配任何标题。