test: add unit tests for ApiService.registerLocation
Cover success (200), duplicate (409), validation error (400), and network failure paths using a MockClient. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
100
test/services/api_service_test.dart
Normal file
100
test/services/api_service_test.dart
Normal file
@@ -0,0 +1,100 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:pad_scanner/services/api_service.dart';
|
||||
|
||||
void main() {
|
||||
group('ApiService.registerLocation', () {
|
||||
test('returns ok on 200', () async {
|
||||
final mockClient = _MockClient((request) async {
|
||||
return http.Response(
|
||||
jsonEncode({'zongpai_no': '26B1', 'location_code': 'A01-02-03', 'created_at': '2026-05-11T10:00:00'}),
|
||||
200,
|
||||
headers: {'content-type': 'application/json; charset=utf-8'},
|
||||
);
|
||||
});
|
||||
final svc = ApiService(client: mockClient);
|
||||
final result = await svc.registerLocation(
|
||||
baseUrl: 'http://localhost',
|
||||
zongpaiNo: '26B1',
|
||||
locationCode: 'A01-02-03',
|
||||
);
|
||||
expect(result.success, isTrue);
|
||||
expect(result.isDuplicate, isFalse);
|
||||
});
|
||||
|
||||
test('returns duplicate on 409 with location_code and registered_at', () async {
|
||||
final mockClient = _MockClient((request) async {
|
||||
return http.Response(
|
||||
jsonEncode({
|
||||
'error_code': 'DUPLICATE_LOCATION',
|
||||
'message': '该总排号已存在货位记录',
|
||||
'location_code': 'A01-02-03',
|
||||
'registered_at': '2026-05-11T10:00:00',
|
||||
}),
|
||||
409,
|
||||
headers: {'content-type': 'application/json; charset=utf-8'},
|
||||
);
|
||||
});
|
||||
final svc = ApiService(client: mockClient);
|
||||
final result = await svc.registerLocation(
|
||||
baseUrl: 'http://localhost',
|
||||
zongpaiNo: '26B1',
|
||||
locationCode: 'A02-01-01',
|
||||
);
|
||||
expect(result.success, isFalse);
|
||||
expect(result.isDuplicate, isTrue);
|
||||
expect(result.duplicateInfo?['location_code'], 'A01-02-03');
|
||||
expect(result.duplicateInfo?['registered_at'], '2026-05-11T10:00:00');
|
||||
});
|
||||
|
||||
test('returns error on 400 with message', () async {
|
||||
final mockClient = _MockClient((request) async {
|
||||
return http.Response(
|
||||
jsonEncode({'error_code': 'INVALID_ZONGPAI', 'message': 'INVALID_ZONGPAI'}),
|
||||
400,
|
||||
headers: {'content-type': 'application/json; charset=utf-8'},
|
||||
);
|
||||
});
|
||||
final svc = ApiService(client: mockClient);
|
||||
final result = await svc.registerLocation(
|
||||
baseUrl: 'http://localhost',
|
||||
zongpaiNo: 'INVALID',
|
||||
locationCode: 'A01-02-03',
|
||||
);
|
||||
expect(result.success, isFalse);
|
||||
expect(result.isDuplicate, isFalse);
|
||||
expect(result.errorMessage, 'INVALID_ZONGPAI');
|
||||
});
|
||||
|
||||
test('returns error on network failure', () async {
|
||||
final mockClient = _MockClient((request) async {
|
||||
throw Exception('Connection refused');
|
||||
});
|
||||
final svc = ApiService(client: mockClient, timeout: Duration(seconds: 1));
|
||||
final result = await svc.registerLocation(
|
||||
baseUrl: 'http://localhost',
|
||||
zongpaiNo: '26B1',
|
||||
locationCode: 'A01-02-03',
|
||||
);
|
||||
expect(result.success, isFalse);
|
||||
expect(result.errorMessage, '网络异常,请检查网络连接');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class _MockClient extends http.BaseClient {
|
||||
final Future<http.Response> Function(http.BaseRequest) _handler;
|
||||
_MockClient(this._handler);
|
||||
|
||||
@override
|
||||
Future<http.StreamedResponse> send(http.BaseRequest request) async {
|
||||
final response = await _handler(request);
|
||||
return http.StreamedResponse(
|
||||
http.ByteStream.fromBytes(response.bodyBytes),
|
||||
response.statusCode,
|
||||
headers: response.headers,
|
||||
reasonPhrase: response.reasonPhrase,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user