cah4a / dart_nock

HTTP requests mocking library for dart and flutter.
https://pub.dev/packages/nock
MIT License
20 stars 14 forks source link

Coverage #3

Open pblinux opened 4 years ago

pblinux commented 4 years ago

Hi!

First, awesome work with nock, is so useful, thanks.

Everything is working great, but when I try to run tests with code coverage, fails. I have a couple of test files, one of those, use nock. To be more specific, the issue is when creating a single test file for group the coverage.

This is what I've tried so far:

This is the main_test.dart file I'm using:

import 'basic_test.dart' as basic_test;
import 'nock_test.dart' as nock_test;

void main() {
  basic_test.main();
  nock_test.main();
}
cah4a commented 4 years ago

Hi @pblinux!

I'm glad to hear that you are enjoying the package!

I've made a simple package with test_coverage and it works well with pub run test_coverage: https://gist.github.com/cah4a/27797abcaf0c206a3e2c959d99dbcd53

Please consider providing more information about the issue and environment you are working on.

pblinux commented 4 years ago

Hi @cah4a, thanks for the reply.

Of course. Let me explain it: I have 6 test files, one use nock to check response failures from an API:

void main() {
  setUpAll(() {
    nock.defaultBase = "https://flusmic.cdn.prismic.io";
    nock.init();
  });
  setUp(nock.cleanAll);

  group('error from prismic', () {
    test('bad request exception', () {
      nock.get("/api/v2")..replay(400, 'data');
      final flusmic =
          Flusmic(prismicEndpoint: 'https://flusmic.cdn.prismic.io/api/v2');
      expect(
          () async => await flusmic.getApi(),
          throwsA(
              isA<FlusmicError>().having((e) => e.code, 'bad request', 400)));
    });
  });
}

pub run test_coverage create the .test_coverage.dart file with all of the tests, but fails with this message:

Unhandled exception:
Tests failed with exit code 255
#0      runTestsAndCollect (package:test_coverage/src/functions.dart:120:5)
<asynchronous suspension>
#1      main (file:///home/pblinux/.pub-cache/hosted/pub.dartlang.org/test_coverage-0.4.1/bin/test_coverage.dart:51:9)
#2      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:299:32)
#3      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

But when I remove this nock test file where I check errors, pub run test_coverage works.

pub run test_coverage works only when nock test file is not included or when is the only test included.

Working with dart 2.8.2 and dio instead of http.

pblinux commented 4 years ago

Hi @cah4a

I've been doing tests and it's because of dio. Using http as client, everything works great.

Maybe it will be useful to clarify that nock works better with http that with dio in readme, what you think?

cah4a commented 4 years ago

Nock doesn't depend on http or other networking libraries. It uses only HttpOverrides from the dart:io and I don't think it's ok that code coverage or some HTTP client libraries not working.

We should investigate that. I hope I will have some time next week to reproduce your error.

pblinux commented 4 years ago

Hi @cah4a

Yes, it's really weird because pub run test works without troubles.

I just created a gist so we can do some tests over it: https://gist.github.com/pblinux/e611501db8c674c97cfa5e3a2117c54d

I'll be searching more about how Dio works, maybe do something in a different way.

cah4a commented 4 years ago

Finally got some time to investigate the issue.

When you run pub run test_coverage you have only one test case, not several. And all setups from all files run simultaneously before any test cases run. Thus you haven't any test without an active nock: it will catch all requests from all test cases.

That's why your tests work with pub run test and falls with pub run test_coverage.

What you can do now? Rewrite all the test cases as shown below:

import 'dart:io';

import 'package:nock/src/overrides.dart';

void main() {
   test('some test with nock', () async {
      await HttpOverrides.runZoned(() {
        nock("https://jsonplaceholder.cypress.io").get("/todos/1")
            ..replay(404, "result");

       expect(() async => await get(), throwsException);
     }, createHttpClient: (context) => MockClient());
  })
}

It's not very convenient cuz you have to repeat that pattern in every test, but it should work.

I'm considering providing another initialization way for injecting nock. Maybe several ways. Have to think about it.

Thanks again for reporting.

pblinux commented 4 years ago

Hi @cah4a

Thank you very much, all is working now with Dio as client.

I think isn't bad at all, just maybe a good idea would be clarify this in the readme to avoid future issues. Maybe a Test Coverage section would be useful since this a specific situation.

Thanks again and if I can help with something, let me know.

cah4a commented 4 years ago

Your welcome!

If you have other questions or suggestions, feel free to open an issue.

RounakTadvi commented 3 years ago

@pblinux Could you share an example how you were able to Mock Dio requests using nock?