84 lines
3.1 KiB
Dart
84 lines
3.1 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
import 'package:qiangbao_accounting/widgets/avatar.dart';
|
||
|
||
/// 头像组件的测试。
|
||
///
|
||
/// 重点是**不崩**和**不留裂图** —— 头像是从后端 /uploads 拉的,
|
||
/// 文件被删、地址写错、网络断了都会走到 errorBuilder,
|
||
/// 那时候必须退回默认图标,而不是显示一个裂开的图。
|
||
void main() {
|
||
Widget wrap(Widget child) => MaterialApp(home: Scaffold(body: child));
|
||
|
||
group('Avatar 兜底', () {
|
||
testWidgets('assetPath 为 null 时显示默认图标,不发起网络请求', (tester) async {
|
||
await tester.pumpWidget(wrap(const Avatar(size: 40)));
|
||
await tester.pump();
|
||
|
||
// 没有 Image 组件 —— 说明压根没去加载图片
|
||
expect(find.byType(Image), findsNothing);
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
|
||
testWidgets('assetPath 为空串时也走默认图标', (tester) async {
|
||
await tester.pumpWidget(wrap(const Avatar(assetPath: '', size: 40)));
|
||
await tester.pump();
|
||
|
||
expect(find.byType(Image), findsNothing);
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
|
||
testWidgets('只有空白字符的路径也当没有(后端可能返回 " ")', (tester) async {
|
||
await tester.pumpWidget(wrap(const Avatar(assetPath: ' ', size: 40)));
|
||
await tester.pump();
|
||
|
||
expect(find.byType(Image), findsNothing);
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
|
||
testWidgets('★ 给了路径就渲染图片,且加载失败时不崩(退回默认图标)', (tester) async {
|
||
await tester.pumpWidget(wrap(
|
||
const Avatar(assetPath: 'persona/2026/09/29/x.jpg', size: 40),
|
||
));
|
||
await tester.pump();
|
||
|
||
expect(find.byType(Image), findsOneWidget);
|
||
|
||
// 测试环境里网络请求必然失败,会走 errorBuilder。
|
||
// 这里断言的是「失败被接住了,没有把异常抛到 widget 树」
|
||
await tester.pump(const Duration(milliseconds: 100));
|
||
expect(tester.takeException(), isNull,
|
||
reason: '图片加载失败必须被 errorBuilder 接住,不能抛异常');
|
||
});
|
||
});
|
||
|
||
group('Avatar 尺寸', () {
|
||
testWidgets('尺寸按传入值设置(聊天气泡和「我的」页面用不同大小)', (tester) async {
|
||
await tester.pumpWidget(wrap(const Avatar(size: 36)));
|
||
await tester.pump();
|
||
|
||
final container = tester.widget<Container>(find.byType(Container).first);
|
||
final size = container.constraints;
|
||
expect(size?.maxWidth, 36);
|
||
expect(size?.maxHeight, 36);
|
||
});
|
||
|
||
testWidgets('不同尺寸都不溢出', (tester) async {
|
||
for (final s in [24.0, 36.0, 40.0, 60.0, 76.0]) {
|
||
await tester.pumpWidget(wrap(Avatar(size: s)));
|
||
await tester.pump();
|
||
expect(tester.takeException(), isNull, reason: '尺寸 $s 出问题了');
|
||
}
|
||
});
|
||
|
||
testWidgets('在很窄的容器里也不溢出', (tester) async {
|
||
await tester.pumpWidget(wrap(
|
||
const SizedBox(width: 40, height: 40, child: Avatar(size: 36)),
|
||
));
|
||
await tester.pump();
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
});
|
||
}
|