Search code examples
dartfluttermockitoflutter-test

Bad state: Mock method was not called within `when()`. Was a real method called?


I'm trying to make a mock of an httpRequest in flutter using mockito.

Here I define a global http client:

library utgard.globals;

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

http.Client httpClient = http.Client();

Then I replace in integration testing:

import 'package:flutter_driver/driver_extension.dart';
import 'package:http/http.dart' as http;
import 'package:utgard/globals.dart' as globals;
import 'package:mockito/mockito.dart';

import 'package:utgard/main.dart' as app;

class MockClient extends Mock implements http.Client {}

void main() {
  final MockClient client = MockClient();
  globals.httpClient = client;

  enableFlutterDriverExtension();

  app.main();
}

Then I try to use when of mockito:

test('login with correct password', () async {
      final client = MockClient();

      when(globals.httpClient.post('http://www.google.com'))
          .thenAnswer((_) async => http.Response('{"title": "Test"}', 200));

      await driver.enterText('000000');
      await driver.tap(loginContinuePasswordButton);
    });

But I receive the following error:

Bad state: Mock method was not called within when(). Was a real method called?


Solution

  • This issue may happen when you implement a method you want to mock instead of letting Mockito do that.

    This code below will return Bad state: Mock method was not called within when(). Was a real method called?:

    class MockFirebaseAuth extends Mock implements FirebaseAuth {
      FirebaseUser _currentUser;
    
      MockFirebaseAuth(this._currentUser);
    
      // This method causes the issue.
      Future<FirebaseUser> currentUser() async {
        return _currentUser;
      }
    }
    
    final user = MockFirebaseUser();
    final mockFirebaseAuth = MockFirebaseAuth(user);
    
    // Will throw `Bad state: Mock method was not called within `when()`. Was a real method called?`
    when(mockFirebaseAuth.currentUser())
        .thenAnswer((_) => Future.value(user));
    

    What do you want instead is:

    class MockFirebaseAuth extends Mock implements FirebaseAuth {}
    
    final user = MockFirebaseUser();
    final mockFirebaseAuth = MockFirebaseAuth();
    
    // Will work as expected
    when(mockFirebaseAuth.currentUser())
        .thenAnswer((_) => Future.value(user));
    

    Also this issue happens when you try to call when() on a non-mock sublass:

    class MyClass {
      String doSomething() {
        return 'test';
      }
    }
    
    final myClassInstance = MyClass();
    
    // Will throw `Bad state: Mock method was not called within `when()`. Was a real method called?`
    when(myClassInstance.doSomething())
        .thenReturn((_) => 'mockedValue');