错误状态:模拟方法未在 `when()` 中调用。调用了真正的方法吗?
Bad state: Mock method was not called within `when()`. Was a real method called?
我正在尝试使用 mockito 在 flutter 中模拟 httpRequest
。
这里我定义了一个全局的http客户端:
library utgard.globals;
import 'package:http/http.dart' as http;
http.Client httpClient = http.Client();
然后我在集成测试中替换:
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();
}
然后我尝试使用 mockito 的 when
:
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);
});
但我收到以下错误:
Bad state: Mock method was not called within when()
. Was a real method called?
我找到的解决方案是在 test_driver/app.dart 中定义模拟,然后调用 runApp
函数,这样你就可以应用甚至使用 flutter 集成测试进行模拟:
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());
}
因为它可以成为一个巨大的代码来模拟那里的所有请求,你可以创建一个单独的函数以便更好地组织代码:
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());
}
当您实现要模拟的方法而不是让 Mockito 执行该操作时,可能会发生此问题。
下面这段代码将 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));
你想要的是:
class MockFirebaseAuth extends Mock implements FirebaseAuth {}
final user = MockFirebaseUser();
final mockFirebaseAuth = MockFirebaseAuth();
// Will work as expected
when(mockFirebaseAuth.currentUser())
.thenAnswer((_) => Future.value(user));
当您尝试在非模拟子类上调用 when()
时 也会发生此问题:
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');
还有一种可能。如果您的模拟对象发生这种情况,那么它可能已经过时了。在这种情况下,请尝试使用
重新生成您的模拟对象
flutter pub run build_runner build --delete-conflicting-outputs
我正在尝试使用 mockito 在 flutter 中模拟 httpRequest
。
这里我定义了一个全局的http客户端:
library utgard.globals;
import 'package:http/http.dart' as http;
http.Client httpClient = http.Client();
然后我在集成测试中替换:
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();
}
然后我尝试使用 mockito 的 when
:
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);
});
但我收到以下错误:
Bad state: Mock method was not called within
when()
. Was a real method called?
我找到的解决方案是在 test_driver/app.dart 中定义模拟,然后调用 runApp
函数,这样你就可以应用甚至使用 flutter 集成测试进行模拟:
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());
}
因为它可以成为一个巨大的代码来模拟那里的所有请求,你可以创建一个单独的函数以便更好地组织代码:
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());
}
当您实现要模拟的方法而不是让 Mockito 执行该操作时,可能会发生此问题。
下面这段代码将 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));
你想要的是:
class MockFirebaseAuth extends Mock implements FirebaseAuth {}
final user = MockFirebaseUser();
final mockFirebaseAuth = MockFirebaseAuth();
// Will work as expected
when(mockFirebaseAuth.currentUser())
.thenAnswer((_) => Future.value(user));
当您尝试在非模拟子类上调用 when()
时 也会发生此问题:
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');
还有一种可能。如果您的模拟对象发生这种情况,那么它可能已经过时了。在这种情况下,请尝试使用
重新生成您的模拟对象flutter pub run build_runner build --delete-conflicting-outputs