// 唯一值得单测的东西:原生异常有没有被挡在包边界内(07 §使用规则)。 import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:native_scan/native_scan.dart'; import 'package:native_scan/src/generated/scan_api.g.dart'; // pigeon 给 @HostApi 生成的是具体类(内部持有 BinaryMessenger), // 所以这里只能 extends 覆写方法,不能 implements。 class _ThrowingApi extends ScanHostApi { _ThrowingApi(this.error); final Object error; @override Future startScan(ScanOptions options) => Future.error(error); @override Future isModeSupported(ScanMode mode) => Future.error(error); } void main() { final ScanOptions options = ScanOptions(mode: ScanMode.barcode); test('PlatformException 被转成 NativeScanException,原生类型不外泄', () async { final NativeScan scan = NativeScan( api: _ThrowingApi(PlatformException(code: 'CANCELLED', message: '用户取消')), ); await expectLater( scan.startScan(options), throwsA( isA() .having((NativeScanException e) => e.code, 'code', NativeScanErrorCode.cancelled) .having((NativeScanException e) => e.isCancelled, 'isCancelled', isTrue), ), ); }); test('原生未实现时抛 UNSUPPORTED_PLATFORM,而不是静默返回', () async { final NativeScan scan = NativeScan(api: _ThrowingApi(MissingPluginException())); await expectLater( scan.startScan(options), throwsA( isA().having( (NativeScanException e) => e.code, 'code', NativeScanErrorCode.unsupportedPlatform, ), ), ); }); test('isModeSupported 出错时降级为 false,调用方据此隐藏入口', () async { final NativeScan scan = NativeScan(api: _ThrowingApi(MissingPluginException())); expect(await scan.isModeSupported(ScanMode.plate), isFalse); }); }