Flutter Bloc测试中late变量未初始化错误的解决办法咨询
问题:Flutter Bloc测试中late变量未初始化错误解决办法
问题现象
- 运行Flutter Bloc测试时触发late变量未初始化错误
- 把late替换为空安全写法后仍报错
- 正常运行程序(不执行Bloc测试)时无异常
测试代码片段
@GenerateMocks([SearchMovies, SearchTvSeriess]) void main() { late SearchMovieBloc searchMovieBloc; late SearchTvSeriesBloc searchTvSeriesBloc; late MockSearchMovies mockSearchMovies; late MockSearchTvSeriess mockSearchTvSeriess; setUp(() { searchTvSeriesBloc = SearchTvSeriesBloc(mockSearchTvSeriess); mockSearchMovies = MockSearchMovies(); searchMovieBloc = SearchMovieBloc(mockSearchMovies); mockSearchTvSeriess = MockSearchTvSeriess(); }); final tTvSeriesModel = TvSeries( originalName: "2 Good 2 Be True", posterPath: "/2Wf5ySCPcnp8lRhbSD7jt0YLz5A.jpg", id: 135647, overview: "Car mechanic Eloy makes a terrible first impression on Ali, who works for a real estate magnate. But both of them are hiding their true personas.", popularity: 943.32, genreIds: [35, 18], backdropPath: "/sIRK4NYe1OK2hOJAg4xxuxzceKk.jpg", voteAverage: 7.5, voteCount: 102); final tTvSeriesList = <TvSeries>[tTvSeriesModel]; final tQuery = 'spiderman'; group('Search Movies', () { test('Initial state should be empty', () { expect(searchMovieBloc.state, SearchEmpty('')); }); blocTest<SearchMovieBloc, SearchState>( 'Should emit [SearchLoading, SearchHasData] when data is gotten successfully', build: () { when(mockSearchMovies.execute(tQuery)) .thenAnswer((_) async => Right(testMovieList)); return searchMovieBloc; }, act: (bloc) => bloc.add(OnQueryChanged(tQuery)), wait: const Duration(milliseconds: 500), expect: () => [ SearchLoading(), SearchHasData(testMovieList), ], verify: (bloc) { verify(mockSearchMovies.execute(tQuery)); }, ); }); }
错误说明
错误提示为:LateInitializationError: Field 'mockSearchTvSeriess' has not been initialized.
解决办法
1. 修正setUp初始化顺序(核心修复)
问题根源是setUp中先实例化SearchTvSeriesBloc时,mockSearchTvSeriess还未被创建,导致late变量未初始化就被使用。调整顺序,先创建mock实例再初始化Bloc:
setUp(() { // 先创建所有mock实例 mockSearchMovies = MockSearchMovies(); mockSearchTvSeriess = MockSearchTvSeriess(); // 再用mock实例初始化Bloc searchMovieBloc = SearchMovieBloc(mockSearchMovies); searchTvSeriesBloc = SearchTvSeriesBloc(mockSearchTvSeriess); });
2. 测试内直接创建Bloc实例(优化方案)
避免复用全局Bloc实例,在blocTest的build方法里直接创建新的Bloc和mock,彻底消除变量初始化顺序问题,同时避免测试间的状态污染:
blocTest<SearchMovieBloc, SearchState>( 'Should emit [SearchLoading, SearchHasData] when data is gotten successfully', build: () { final mock = MockSearchMovies(); when(mock.execute(tQuery)) .thenAnswer((_) async => Right(testMovieList)); return SearchMovieBloc(mock); // 直接创建新的Bloc实例 }, act: (bloc) => bloc.add(OnQueryChanged(tQuery)), wait: const Duration(milliseconds: 500), expect: () => [ SearchLoading(), SearchHasData(testMovieList), ], verify: (bloc) { verify(bloc.searchMovies.execute(tQuery)); // 直接验证Bloc内的实例 }, );
3. 使用late final(应急方案)
如果坚持使用全局变量,可将late改为late final,确保变量只被初始化一次,但这只是规避错误,不如调整顺序彻底:
late final SearchMovieBloc searchMovieBloc; late final SearchTvSeriesBloc searchTvSeriesBloc; late final MockSearchMovies mockSearchMovies; late final MockSearchTvSeriess mockSearchTvSeriess;
内容的提问来源于stack exchange,提问作者dendi
相关产品推荐
相关产品推荐

