Files
2026-09-04 15:22:20 +08:00

129 lines
4.1 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 单元测试:UserModel 的 JSON 解析兼容点
//
// 为什么测它:CurrentUserExtension.fromJson 里有 4 个"抗后端漂移"
// 的兼容点(见 user_model.dart 注释),任何一项回归都会导致线上
// 解析崩或字段丢,必须用测试锁死:
// ① data 包装:接口返回 {code, message, data:{...}} 时取 data;
// ② 字符串数字:userId/classId 后端可能返回 "820466383020136";
// ③ 缺字段兜底:后端漏字段时用默认值,不闪崩;
// ④ toJson/fromJson 必须成对,否则缓存回填丢字段。
//
// 运行:flutter test test/models/user_model_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:new_learn/core/models/user_model.dart';
void main() {
group('CurrentUserExtension.fromJson', () {
test('① data 包装:取 json["data"],忽略外层 code/message', () {
final user = CurrentUserExtension.fromJson({
'code': 200,
'message': 'ok',
'data': {'userId': 1001, 'userName': '小明', 'userPoints': 88.5},
});
expect(user.userId, 1001);
expect(user.userName, '小明');
expect(user.userPoints, 88.5);
});
test('① 直接返回(没有 data 包装)也支持', () {
final user = CurrentUserExtension.fromJson({
'userId': 7,
'userName': '小李',
});
expect(user.userId, 7);
expect(user.userName, '小李');
});
test('② 字符串数字:userId/classId/userPoints 传字符串能正确转换', () {
final user = CurrentUserExtension.fromJson({
'data': {
'userId': '820466383020136', // 大数必须 int 不丢精度
'classId': '12',
'userPoints': '105.5',
'graduationYear': '2026',
},
});
expect(user.userId, 820466383020136);
expect(user.classId, 12);
expect(user.userPoints, 105.5);
expect(user.graduationYear, 2026);
});
test('② 非法字符串数字兜底为 0,不抛异常', () {
final user = CurrentUserExtension.fromJson({
'data': {'userId': 'abc', 'userPoints': 'xyz'},
});
expect(user.userId, 0);
expect(user.userPoints, 0.0);
});
test('③ 空 JSON:全部字段走默认值,不闪崩', () {
final user = CurrentUserExtension.fromJson({});
expect(user.userId, 0);
expect(user.userName, '');
expect(user.userPoints, 0.0);
expect(user.levelName, '');
expect(user.isShowGuide, false);
expect(user.isShowReport, false);
expect(user.id, 0);
});
test('④ toJson/fromJson 往返一致(缓存回填不丢字段)', () {
const user = CurrentUserExtension(
userId: 1001,
userName: '小明',
userPoints: 88.5,
levelName: '青铜',
avatar: 'https://x/a.png',
className: '高三(1)班',
classId: 12,
gradeLevel: '高三',
graduationYear: 2026,
targetConfigId: 3,
targetConfigName: '目标A',
userAvatarStatus: 1,
userAvatarReason: '待审核',
isShowGuide: true,
isShowReport: true,
id: 99,
);
final roundTrip = CurrentUserExtension.fromJson(user.toJson());
expect(roundTrip.userId, user.userId);
expect(roundTrip.userName, user.userName);
expect(roundTrip.userPoints, user.userPoints);
expect(roundTrip.levelName, user.levelName);
expect(roundTrip.className, user.className);
expect(roundTrip.isShowGuide, user.isShowGuide);
expect(roundTrip.userAvatarReason, user.userAvatarReason);
});
});
group('UserPointLevel.fromJson', () {
test('数字字段解析 + 默认值兜底', () {
final level = UserPointLevel.fromJson({
'userId': 1001,
'totalPoints': 500,
'level': 2,
});
expect(level.userId, 1001);
expect(level.totalPoints, 500);
expect(level.level, 2);
expect(level.levelUpPoints, 0); // 缺字段走默认值
final empty = UserPointLevel.fromJson({});
expect(empty.totalPoints, 0);
expect(empty.level, 0);
});
});
}