http-mock-adapter icon indicating copy to clipboard operation
http-mock-adapter copied to clipboard

Dio object calls backend instead of returning the value set to dioAdapter.onPost.

Open vadrian89 opened this issue 3 years ago • 0 comments

Description

Hello,

I have Dio initialised inside a repository class which ends up calling the server instead of returning what I am setting using dioAdapter.onPost. The issue occurs if I use the same repository object initialised at the start of the group. If I reinitialise the object before each test, the issue is not occuring.

In the code below the "Test reloadUser method" ends up calling the backend instead of returning what I set in "repository.dioAdapter.onPost".

Steps to reproduce

  1. Initialise Dio object inside a different class;
  2. set onPost to return a valid response and test it;
  3. set onPost to throw an error and test it;
  4. set onPost to return a valid response and test it; at this point the post method ends up calling the real server;

Expected behavior

In my opinion the dio.post should not try and request data from real server if dioAdapter.onPost is set multiple times.

Example code

void main() async {
  PathProviderPlatform.instance = FakePathProviderPlatform();
  await Hive.initFlutter();
  await SharedPrefs().init();

  group("AuthenticationRepository test:", () {
    const successResult = ServerResult.success();
    final failureResult = ServerResult<dynamic>.failure(unexpectedError);

    final responseData = jsonEncode({
      "userid": 2235311321321,
      "name": "username",
    });

    late MockAuthenticationRepository repository;

    setUp(() => repository = MockAuthenticationRepository());

    test(
      "Test signIn method",
      () async {
        /// Set-up onPost stub
        repository.dioAdapter.onPost(
          GeneralEndpoints.signIn.toString(),
          (server) => server.reply(200, responseData),
        );

        const request = AuthenticationRequestBody.signIn(
          email: "[email protected]",
          password: "password",
        );

        /// Setup expectLater to listen for new data on the [repository.resultStream] stream.
        expectLater(repository.resultStream, emits(successResult));

        /// Make the call to [repository.signIn].
        await repository.signIn(request);

        /// Ensure the user was stored locally.
        expect(SharedPrefs().user, UserModel.fromJson(jsonDecode(responseData)));

        /// Setup stub for error.
        repository.dioAdapter.onPost(
          GeneralEndpoints.signIn.toString(),
          (server) => server.throws(
            401,
            d.DioError(requestOptions: d.RequestOptions(path: GeneralEndpoints.signIn.path)),
          ),
        );

        /// Check the response is a [ServerResult.failure], as expected.
        expectLater(repository.resultStream, emits(failureResult));

        /// Make the call to [repository.signIn].
        await repository.signIn(request);
      },
    );

    /// If I set this, than the test works as expected.
    /// setUp(() => repository = MockAuthenticationRepository());

    test(
      "Test reloadUser method",
      () async {
        /// Set-up onPost stub
        repository.dioAdapter.onPost(
          GeneralEndpoints.refreshUser.toString(),
          (server) => server.reply(200, responseData),
        );

        /// Setup expectLater to listen for new data on the [repository.resultStream] stream.
        expectLater(repository.resultStream, emits(successResult));

        /// Make the call to [repository.signIn].
        await repository.reloadUser();

        /// Ensure the user was stored locally.
        expect(SharedPrefs().user, UserModel.fromJson(jsonDecode(responseData)));
      },
    );

    test(
      "Test the close() method",
      () async {
        await repository.close();
        expect(repository.isClosed, isTrue);
      },
    );
  });
}

System details

[✓] Flutter (Channel stable, 3.0.3, on Ubuntu 22.04 LTS 5.15.0-40-generic, locale ro_RO.UTF-8) [✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0) [✓] Chrome - develop for the web [✓] Linux toolchain - develop for Linux desktop [✓] Android Studio (version 2021.2) [✓] VS Code [✓] Connected device (3 available) [✓] HTTP Host Availability

Best regards, Adrian

vadrian89 avatar Jun 29 '22 10:06 vadrian89