Reputation: 8184
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?
Upvotes: 41
Views: 28483
Reputation: 1
please declare resetMocktailState()
in teardown or at the end of setup, so the test cases should not affect later test cases.
Upvotes: 0
Reputation: 243
There is one more possibility. If this happens to your mock object, then probably it may be outdated. In this case, try regenerating your mock objects by using
flutter pub run build_runner build --delete-conflicting-outputs
Upvotes: 3
Reputation: 32529
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');
Upvotes: 52
Reputation: 8184
The solution I found was to define the mock in test_driver/app.dart and call the runApp
function after that, this way you can apply the mock even with flutter integration testing:
import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:utgard/business/config/globals.dart';
import 'package:utgard/main.dart' as app;
class MockClient extends Mock implements http.Client {}
void main() {
enableFlutterDriverExtension();
final MockClient client = MockClient();
// make your mocks here
httpClient = client;
runApp(app.MyApp());
}
Since it can become a huge code to mock all the requests there you can make a separate function in order to better organize the code:
import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:utgard/business/config/globals.dart';
import 'package:utgard/main.dart' as app;
class MockClient extends Mock implements http.Client {}
void main() {
enableFlutterDriverExtension();
final MockClient client = MockClient();
makeMock();
httpClient = client;
runApp(app.MyApp());
}
Upvotes: -2