felangel / mocktail

A mock library for Dart inspired by mockito
https://pub.dev/packages/mocktail
MIT License
617 stars 81 forks source link

Question: type 'Null' is not a subtype of type 'Future<Response> on http post test #80

Closed Flavio-Vieirastack closed 2 years ago

Flavio-Vieirastack commented 2 years ago

hello guys, if there is someone there who can help me i would appreciate it too much. I'm testing a post type request, my goal is to ensure that the class will receive the correct url, but I'm getting this error:

type 'Null' is not a subtype of type 'Future'

My code:

import 'package:faker/faker.dart';
import 'package:http/http.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';

class HttpAdapter {
  final Client client;

  HttpAdapter({required this.client});

  Future<void> request({
    required Uri url,
  }) async {}
}

class ClientSpy extends Mock implements Client {}

void main() {
  group("post", () {
    test("deve chamar o metodo post com valores corretos", () async {
      final client = ClientSpy();
      final sut = HttpAdapter(client: client);
      final url = faker.internet.httpUrl();
      final Uri uri = Uri.parse(url);

      await sut.request(url: uri);
      client.post(uri);

      verify(() => client.post(uri)).called(1);
    });
  });
}
felangel commented 2 years ago

Hi @Flavio-Vieirastack ๐Ÿ‘‹ Thanks for opening an issue!

I'm guessing you're missing the stub for client.post:

when(() => client.post(uri)).thenAnswer((_) async {});

Let me know if that helps ๐Ÿ‘

Flavio-Vieirastack commented 2 years ago

thanks so much for the reply @ mรกs i'm new to the world of testing, could you give me an example? I did as in the code below but I have a compilation error "The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. Try adding either a return or a throw statement at the end."

my code:

import 'package:faker/faker.dart';
import 'package:http/http.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';

class HttpAdapter {
  final Client client;

  HttpAdapter({required this.client});

  Future<void> request({
    required Uri url,
  }) async {
    await client.post(url);
  }
}

class ClientSpy extends Mock implements Client {}

void main() {
  group("post", () {
    test("deve chamar o metodo post com valores corretos", () async {
      final client = ClientSpy();
      final sut = HttpAdapter(client: client);
      final url = faker.internet.httpUrl();
      final Uri uri = Uri.parse(url);

      await sut.request(url: uri);
      client.post(uri);

      when(() => client.post(uri)).thenAnswer((_) async {

      });

      verify(() => client.post(uri)).called(1);
    });
  });
}

sorry for the insistence, i've been trying to do this test for days

felangel commented 2 years ago

@Flavio-Vieirastack no problem, the following test works as expected:

import 'package:faker/faker.dart';
import 'package:http/http.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';

class HttpAdapter {
  final Client client;

  HttpAdapter({required this.client});

  Future<void> request({
    required Uri url,
  }) async {
    await client.post(url);
  }
}

class ClientSpy extends Mock implements Client {}

void main() {
  group("post", () {
    test("deve chamar o metodo post com valores corretos", () async {
      final url = faker.internet.httpUrl();
      final Uri uri = Uri.parse(url);
      final client = ClientSpy();
      final sut = HttpAdapter(client: client);

      when(() => client.post(uri)).thenAnswer((_) async => Response('{}', 200));

      await sut.request(url: uri);

      verify(() => client.post(uri)).called(1);
    });
  });
}

Hope that helps ๐Ÿ‘

Flavio-Vieirastack commented 2 years ago

thank you so much my friend you are a saint. God bless you

vinay-mars commented 3 months ago

Getting this error 'type 'Null' is not a subtype of type 'Future @felangel


class MockHTTPClient extends Mock implements Client {}

void main() {
  late ApiManager apiManager;
  late MockHTTPClient mockHTTPClient;

  setUp(() {
    mockHTTPClient = MockHTTPClient();
    apiManager = ApiManager(mockHTTPClient);
  });

 test(
        'given UserRepository class when getUser function is called and status code is 200 then a usermodel should be returned',
        () async {
          // Arrange
          const mockResponse = '{"status": "200"}';
          String url = "url";

          when(() {
            return mockHTTPClient.post(Uri.parse(url));
          }).thenAnswer((invocation) => Future.delayed(Durations.short2,() => Response(mockResponse, 200),), );

          // Act
          final user = await apiManager.userLoginApi();
          // Assert
          expect(isuserExist, isA<Data()>());
        },
      );

Future<Data> userLoginApi({String? email, String? password}) async {
    final response = await client.post(
      Uri.parse('url'),
    );
    if (response.statusCode == 200) {
      Map<String, String> body = {
        "email": email.toString(),
        "password": password.toString()
      };

      return Data.fromJson(body);
    }
    throw Exception('Some Error Occurred');
  }

Also, what should i pass in the body. It's a user login api which includes email and pass. Since its a test case i cant pass the user credentials.