单元测试返回属性为<Closure: () => Type>且持续失败排查
问题现象
开展单元测试时,读取Service类属性做断言,所有属性的断言结果均返回闭包而非实际值,报错信息如下:
Expected: <X> Actual: Closure: () => Type>
提前打印属性值可以看到输出符合预期(loggedInUser打印为null),项目使用stacked包实现依赖注入,相关报错截图如下:
测试代码片段:
void main() { group('TestService Tests -', () { TestService sut; setUp(() { registerServices(); }); tearDown(() { unregisterServices(); }); group('Initialize -', () { test('Determine authpage type when not logged in', () async { sut = TestService(); User? result = sut.loggedInUser; print('Sut is equal to ${sut.loggedInUser}'); expect(() => result, null); });
被测Service代码片段:
class TestService { final AuthenticationService _firebaseAuth = locator<AuthenticationService>(); final SharedPreferencesService _prefs = locator<SharedPreferencesService>(); final Logger _log = getLogger('LoginAndUserService'); User? _loggedInUser = null; User? get loggedInUser => _loggedInUser; late bool _firstTimeUsingApp; bool? get firstTimeUsingApp => _firstTimeUsingApp; LoginStatus _currentLoginStatus = LoginStatus.notInitialized; LoginStatus get currentLoginStatus => _currentLoginStatus; }
根本原因
该问题和stacked依赖注入框架无关,是测试断言的写法错误:expect方法的第一个参数需要传入待校验的实际值,但代码里传入的是() => result——这是Dart中无参匿名闭包的简写语法,传入的是一个函数对象,而非result变量存储的属性值,因此断言拿到的实际结果永远是闭包对象,和预期值不匹配。expect前打印sut.loggedInUser能得到正确的null值,是因为打印时直接读取了属性值,没有包裹闭包。
修复方案
- 修改断言语句,移除包裹值的闭包语法,直接传入待校验的值即可:
// 错误写法 // expect(() => result, null); // 正确写法1:使用提前赋值的result变量 expect(result, null); // 正确写法2:直接读取属性传入,无需提前赋值给中间变量 expect(sut.loggedInUser, null); - 额外注意:被测类中
_firstTimeUsingApp是late bool类型,没有在构造函数中初始化,后续测试如果要访问firstTimeUsingApp属性,必须先执行对应初始化逻辑,否则会抛出延迟初始化异常。
内容的提问来源于stack exchange,提问作者Charlie Page
相关产品推荐
相关产品推荐

