面试题答案
一键面试- 引入依赖:
在
pubspec.yaml
文件中添加mockito
和flutter_test
依赖:
然后运行dev_dependencies: mockito: ^[最新版本号] flutter_test: sdk: flutter
flutter pub get
。 - 定义网络请求接口和数据模型:
假设我们有一个网络请求接口和数据模型。例如:
// 数据模型 class Item { final String name; Item(this.name); } // 网络请求接口 abstract class NetworkService { Future<List<Item>> fetchItems(); }
- 创建Mock对象:
使用
mockito
生成Mock对象。在项目根目录运行flutter pub run build_runner build
,会在test/mocks
目录下生成Mock类。假设生成的Mock类为MockNetworkService
:import 'package:mockito/mockito.dart'; import 'package:your_project/network_service.dart'; class MockNetworkService extends Mock implements NetworkService {}
- 设置模拟响应数据:
在测试用例中设置模拟响应数据。例如:
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:your_project/item_widget.dart'; import 'package:your_project/network_service.dart'; import 'package:mockito/mockito.dart'; void main() { group('ItemWidgetTest', () { late MockNetworkService mockNetworkService; setUp(() { mockNetworkService = MockNetworkService(); }); testWidgets('Displays items when network request is successful', (WidgetTester tester) async { final List<Item> mockItems = [Item('Item 1'), Item('Item 2')]; when(mockNetworkService.fetchItems()).thenAnswer((_) async => mockItems); await tester.pumpWidget(MaterialApp( home: ItemWidget(networkService: mockNetworkService), )); await tester.pumpAndSettle(); expect(find.text('Item 1'), findsOneWidget); expect(find.text('Item 2'), findsOneWidget); }); }); }
- 验证不同网络响应情况下的UI表现:
- 成功响应:如上述代码,验证列表项是否正确显示。
- 失败响应:模拟网络请求失败,验证UI是否显示相应的错误提示。例如:
testWidgets('Displays error when network request fails', (WidgetTester tester) async { when(mockNetworkService.fetchItems()).thenThrow(Exception('Network error')); await tester.pumpWidget(MaterialApp( home: ItemWidget(networkService: mockNetworkService), )); await tester.pumpAndSettle(); expect(find.text('Network error'), findsOneWidget); });
在ItemWidget
中,需要在initState
或didChangeDependencies
中调用networkService.fetchItems()
,并根据结果更新UI。例如:
class ItemWidget extends StatefulWidget {
final NetworkService networkService;
ItemWidget({required this.networkService});
@override
_ItemWidgetState createState() => _ItemWidgetState();
}
class _ItemWidgetState extends State<ItemWidget> {
List<Item>? items;
String? error;
@override
void initState() {
super.initState();
_fetchItems();
}
Future<void> _fetchItems() async {
try {
final fetchedItems = await widget.networkService.fetchItems();
setState(() {
items = fetchedItems;
});
} catch (e) {
setState(() {
error = e.toString();
});
}
}
@override
Widget build(BuildContext context) {
if (error!= null) {
return Center(child: Text(error!));
}
if (items == null) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: items!.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items![index].name));
},
);
}
}