如何解决单元测试 GetxController
我是 tdd 的初学者,所以如果这是一个愚蠢的问题,请原谅我。
我在对 GetxControllers 进行单元测试时遇到困难。有谁知道这样做的简单方法? 每当我这样做时,我都会收到错误,因为 Get 正在调用 onStart 并且它不喜欢 Mockito 给出的结果。我尝试使用 Mockito 5.0.1 的自动生成代码以及旧语法,类 MockController 扩展 Mock 实现 Controller{},以及扩展 Fake。
自动生成的代码有构建错误,因为 Mockito 正在尝试使用 _InternalFinalCallback,但它没有被导入,因为它是私有的。我尝试将那部分代码复制粘贴到我生成的文件中(并关闭 pub build watch)但首先这是一个短期解决方案,它有自己的问题,第二它仍然不起作用,因为 onStart 和 onDelete 函数现在告诉我它们不是有效的覆盖。
另外,我可以看到 get_test 包,但它的文档基本上是 0,在示例中,控制器只是直接使用——从来没有模拟控制器。
我尝试设置 Get.testMode = true;但同样,这似乎没有任何作用。虽然我在文档中找到了该属性,但我没有找到如何正确使用它。
任何帮助将不胜感激,
这是我的代码,但问题似乎出在 GetxControllers 上,所以我认为它不太相关:
class FakeAuthController extends Fake implements AuthController {}
@GenerateMocks([AuthController])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late MockAuthController mockAuthController;
late FakeAuthController fakeAuthController;
late SessionController sessionController;
setUp(() {
Get.testMode = true;
mockAuthController = MockAuthController();
fakeAuthController = FakeAuthController();
Get.put<AuthController>(mockAuthController);
sessionController = SessionController();
});
tearDown(() {
Get.delete<AuthController>();
});
group('getSessionInfo',() {
test('Calls authFacade getSignedInUserId',() async {
await sessionController.getSessionInfo();
when(Get.find<AuthController>()).thenReturn(fakeAuthController);
verify(mockAuthController.getSignedInUserId());
});
});
}
我的 AuthController 和会话控制器中确实没有任何东西,但是代码如下:
import 'package:get/get.dart';
class AuthController extends GetxController {
String getSignedInUserId() {
// await Future.delayed(Duration(milliseconds: 1));
return '1';
}
}
import 'package:get/get.dart';
import '../../auth/controllers/auth_controller.dart';
import '../models/session_info.dart';
class SessionController extends GetxController {
final AuthController authController = Get.find<AuthController>();
Rx<SessionInfo> sessionInfo = Rx<SessionInfo>();
Future<void> getSessionInfo() async {
// authController.getSignedInUserId();
// sessionInfo.value = SessionInfo(userId: userId);
}
}
以及自动生成的、有问题的模拟控制器:
// Mocks generated by Mockito 5.0.1 from annotations
// in smart_locker_controller/test/shared/controllers/session_controller_test.dart.
// Do not manually edit this file.
import 'dart:ui' as _i4;
import 'package:get/get_instance/src/lifecycle.dart' as _i2;
import 'package:get/get_state_manager/src/simple/list_notifier.dart' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:smart_locker_controller/auth/controllers/auth_controller.dart'
as _i3;
// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis
class _Fake_InternalFinalCallback<T> extends _i1.Fake
implements _i2._InternalFinalCallback<T> {}
/// A class which mocks [AuthController].
///
/// See the documentation for Mockito's code generation for more information.
class MockAuthController extends _i1.Mock implements _i3.AuthController {
MockAuthController() {
_i1.throwOnMissingStub(this);
}
@override
int get notifierVersion =>
(super.noSuchMethod(Invocation.getter(#notifierVersion),returnValue: 0)
as int);
@override
int get notifierMicrotask =>
(super.noSuchMethod(Invocation.getter(#notifierMicrotask),returnValue: 0)
as int);
@override
bool get hasListeners =>
(super.noSuchMethod(Invocation.getter(#hasListeners),returnValue: false)
as bool);
@override
int get listeners =>
(super.noSuchMethod(Invocation.getter(#listeners),returnValue: 0)
as int);
@override
_i2._InternalFinalCallback<void> get onStart =>
(super.noSuchMethod(Invocation.getter(#onStart),returnValue: _Fake_InternalFinalCallback<void>())
as _i2._InternalFinalCallback<void>);
@override
_i2._InternalFinalCallback<void> get onDelete =>
(super.noSuchMethod(Invocation.getter(#onDelete),returnValue: _Fake_InternalFinalCallback<void>())
as _i2._InternalFinalCallback<void>);
@override
bool get initialized =>
(super.noSuchMethod(Invocation.getter(#initialized),returnValue: false)
as bool);
@override
bool get isClosed =>
(super.noSuchMethod(Invocation.getter(#isClosed),returnValue: false)
as bool);
@override
String getSignedInUserId() =>
(super.noSuchMethod(Invocation.method(#getSignedInUserId,[]),returnValue: '') as String);
@override
void update([List<Object>? ids,bool? condition = true]) =>
super.noSuchMethod(Invocation.method(#update,[ids,condition]),returnValueForMissingStub: null);
@override
void refreshGroup(Object? id) =>
super.noSuchMethod(Invocation.method(#refreshGroup,[id]),returnValueForMissingStub: null);
@override
void removeListener(_i4.VoidCallback? listener) =>
super.noSuchMethod(Invocation.method(#removeListener,[listener]),returnValueForMissingStub: null);
@override
void removeListenerId(Object? id,_i4.VoidCallback? listener) =>
super.noSuchMethod(Invocation.method(#removeListenerId,[id,listener]),returnValueForMissingStub: null);
@override
_i5.Disposer addListener(_i5.GetStateUpdate? listener) =>
(super.noSuchMethod(Invocation.method(#addListener,returnValue: () {}) as _i5.Disposer);
@override
_i5.Disposer addListenerId(Object? key,_i5.GetStateUpdate? listener) =>
(super.noSuchMethod(Invocation.method(#addListenerId,[key,returnValue: () {}) as _i5.Disposer);
@override
void disposeId(Object? id) =>
super.noSuchMethod(Invocation.method(#disposeId,returnValueForMissingStub: null);
}
解决方法
尝试将您的假控制器定义更改为:
class FakeAuthController extends GetxController with Fake implements AuthController {}
不确定这是否适用于 Fake
,但我刚刚用它解决了 Mock
的类似问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。