0

I want to test my GraphQL Query. I have my GraphQL client, and I use a remote datasource to do my requests.

class MockGraphQLClient extends Mock implements GraphQLClient {}

void main() {
  RemoteDataSource RemoteDataSource;
  MockGraphQLClient mockClient;

  setUp(() {
    mockClient = MockGraphQLClient();
    RemoteDataSource = RemoteDataSource(client: mockClient);
  });
  group('RemoteDataSource', () {
    group('getDetails', () {
      test(
          'should preform a query with get details with id variable',
          () async {
        final id = "id";
        when(
          mockClient.query(
            QueryOptions(
              documentNode: gql(Queries.getDetailsQuery),
              variables: {
                'id': id,
              },
            ),
          ),
        ).thenAnswer((_) async => QueryResult(
            data: json.decode(fixture('details.json'))['data'])));

        await RemoteDataSource.getDetailsQuery(id);

        verify(mockClient.query(
          QueryOptions(
            documentNode: gql(Queries.getDetailsQuery),
            variables: {
              'id': id,
            },
          ),
        ));
      });
    });
  });
}

I would like to know how to mock the response of my query. Currently it does not return a result, it returns null But I don't understand why my query returns null, although I have mocked my client, and in my "when" method I use a "thenAnwser" to return the desired value

final GraphQLClient client;

  ChatroomRemoteDataSource({this.client});

  @override
  Future<Model> getDetails(String id) async {
    try {
      final result = await client.query(QueryOptions(
        documentNode: gql(Queries.getDetailsQuery),
        variables: {
          'id': id,
        },
      )); // return => null ????

      if (result.data == null) {
        return [];
      }
      return result.data['details']
    } on Exception catch (exception) {
      throw ServerException();
    }
  }
Kol2gaR
  • 202
  • 2
  • 13
  • Just to get some confusion out of the way, are both code snippets still in sync? I see 'RemoteDataSource' vs 'ChatroomRemoteDataSource' and 'getDetailsQuery' vs 'getDetails' – dumazy Feb 08 '21 at 22:03

3 Answers3

2

The argument on which when should mock an answer for is quite complex. You might be easier to just use any in your test case.

when(mockClient.query(any)).thenAnswer((_) async => QueryResult(
        data: json.decode(fixture('details.json'))['data'])));

any is provided by Mockito to match any argument.

dumazy
  • 13,857
  • 12
  • 66
  • 113
  • I am facing the same issue, however, I am not able to use any in null safe. Do you know what can we use in that case? – Mobile_Dev Dec 14 '21 at 10:29
  • 1
    Null safety added a level of complexity to Mockito. There are multiple approaches documented for null safety: https://github.com/dart-lang/mockito/blob/master/NULL_SAFETY_README.md Personally, I use the generated mocks approach. – dumazy Dec 14 '21 at 13:53
  • 1
    Thank you! It worked for me as well. – Mobile_Dev Dec 15 '21 at 14:18
0

In the

graphql_flutter: ^5.0.0

you need the add source as null or QueryResultSource.network, when call method when can you pass any so you don't need to pass QueryOptions( documentNode: gql(Queries.getDetailsQuery), variables: { 'id': id, }, ),

here is final code: when(mockClient.query(any)).thenAnswer((_) async => QueryResult( data: json.decode(fixture('details.json'))['data'], ,source: null)));

0

any is not accepted with graphQLClient.query(any)) as it accepts non nullable QueryOptions<dynamic>

Using mockito: ^5.1.0 , you will get the warning: The argument type 'Null' can't be assigned to the parameter type 'QueryOptions<dynamic>'

I solved it by creating the mocked QueryOptions as:

class SutQueryOption extends Mock implements QueryOptions {}

void main() {
SutQueryOption _mockedQueryOption;
....

setUp(() {

SutQueryOption _mockedQueryOption = MockedQueryOptions();
....

});

when(mockClient.query(_mockedQueryOption)).thenAnswer((_) async => ....
Jiten Basnet
  • 1,623
  • 15
  • 31