Flutter GetX单元测试报Null非RxString子类型错误问题咨询
错误成因
使用Mockito生成的MockSwitchController是基于类接口生成的空实现模拟类,不会执行真实SwitchController的构造逻辑,也不会初始化类内部声明的成员变量。访问sut.selectedPill时,Mock对象对未打桩的属性默认返回null,但selectedPill的静态类型为非空的RxString(.obs语法生成的响应式字符串类型),null无法匹配非空RxString类型要求,因此抛出类型错误。
另外真实SwitchController初始化时会自动执行Get.put(DateNavigationController())注入依赖,Mock类不会执行这段逻辑,后续测试涉及关联依赖时也会触发异常。
修复方案
根据测试场景二选一即可:
方案1:直接使用真实Controller实例(适配当前测试场景)
当前测试仅校验Controller自身属性初始值,不需要Mock隔离依赖,直接实例化真实Controller即可,注意提前开启GetX测试模式避免依赖注入报错:
void main() { late SwitchController sut; setUp(() { // 开启GetX测试模式,跳过全局上下文校验 Get.testMode = true; sut = SwitchController(); sut.onInit(); }); tearDown(() { sut.dispose(); // 清空GetX实例池,避免用例间状态污染 Get.reset(); }); test('selectedPill初始值为week', () { expect(sut.selectedPill.value, "week"); }); }
方案2:必须Mock Controller场景下手动打桩属性
如果后续测试需要隔离Controller其他逻辑、模拟特定返回行为,需要在访问属性前对响应式变量手动打桩:
- 如果是手写Mock类,直接重写对应属性返回固定值即可:
class MockSwitchController extends Mock implements SwitchController { @override final RxString selectedPill = "week".obs; @override final RxInt labelIndex = 0.obs; }
- 如果是通过Mockito注解自动生成Mock类,在测试setUp阶段通过
when语法打桩:
@GenerateMocks([SwitchController]) void main() { late MockSwitchController sut; setUp(() { Get.testMode = true; sut = MockSwitchController(); // 手动给属性打桩 when(() => sut.selectedPill).thenReturn("week".obs); }); tearDown(() { sut.dispose(); Get.reset(); }); test('selectedPill初始值为week', () { expect(sut.selectedPill.value, "week"); }); }
内容的提问来源于stack exchange,提问作者Sanjay Sanjel
相关产品推荐
相关产品推荐

