Flutter 安全存储测试
Flutter secure storage test
美好的一天!
我需要测试 flutter secure storage 的一些功能。例如storage.saveAccessToken
我已经制作了 MockFlutterStorage 来模拟存储中的保存,但是它不起作用。
这是我的代码:
@GenerateMocks([mockFlutterSecureStorage.FlutterSecureStorage])
void main() {
group('#accessToken', () {
test('Save accessToken in a storage', () async {
final mockFlutterSecureStorage = MockFlutterSecureStorage();
String accessToken = 'a1';
final storage = SecureStorage();
when(mockFlutterSecureStorage.write(
key: 'accessToken', value: accessToken))
.thenAnswer((value) async => {
await storage.saveAccessToken(accessToken);
});
expect(storage.accessToken, 'a1');
});
});
}
应该添加新的答案来举个例子。请注意,我正在使用 mocktail。解释一下这个想法我觉得够了
user_secure_data_source.dart
import 'dart:convert';
import 'package:flutter_app/core/error/exception.dart';
import 'package:flutter_app/features/auth/data/models/models.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
abstract class UserSecureDataSource {
Future<AccessTokenModel> getSavedAccessToken();
void saveAccessToken(AccessTokenModel accessToken);
}
const savedToken = 'SAVED_TOKEN';
class UserSecureDataSourceImpl implements UserSecureDataSource {
UserSecureDataSourceImpl({required this.secureStorage});
final FlutterSecureStorage secureStorage;
@override
Future<AccessTokenModel> getSavedAccessToken() async {
final jsonString = await secureStorage.read(key: savedToken);
if (jsonString != null) {
return Future.value(AccessTokenModel.fromJson(json.decode(jsonString)));
} else {
throw NotFoundSavedTokenSecureException();
}
}
@override
Future<void> saveAccessToken(AccessTokenModel accessToken) async {
return secureStorage.write(
key: savedToken, value: json.encode(accessToken));
}
}
user_secure_data_source_test.dart
import 'dart:convert';
import 'package:flutter_app/core/error/exception.dart';
import 'package:flutter_app/features/auth/data/datasources/user_secure_data_source.dart';
import 'package:flutter_app/features/auth/data/models/models.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:test/test.dart';
import 'package:mocktail/mocktail.dart';
import '../../../../fixtures/fixtures_reader.dart';
class MockFlutterSecureStorage extends Mock implements FlutterSecureStorage {}
void main() {
late UserSecureDataSourceImpl dataSource;
late MockFlutterSecureStorage mockSecureStorage;
final tAccessToken = AccessTokenModel.fromJson(
json.decode(fixture('access_token_model.json')));
setUp(() {
mockSecureStorage = MockFlutterSecureStorage();
dataSource = UserSecureDataSourceImpl(secureStorage: mockSecureStorage);
});
group('UserSecureDataSourceIml', () {
group('getSavedAccessToken', () {
test(
'should return AccessTokenModel from FlutterSecureStorage when there is one the saved',
() async {
// arrange
when(() => mockSecureStorage.read(key: savedToken))
.thenAnswer((_) async => fixture('access_token_model.json'));
// act
final result = await dataSource.getSavedAccessToken();
//assert
verify(() => mockSecureStorage.read(key: savedToken));
expect(result, equals(tAccessToken));
});
test(
'should throw a NotFoundSavedTokenSecureException when is not saved token',
() async {
// arrange
when(() => mockSecureStorage.read(key: savedToken))
.thenAnswer((_) async => null);
// act
final call = dataSource.getSavedAccessToken;
//assert
expect(() => call(), throwsA(isA<NotFoundSavedTokenSecureException>()));
});
});
group('saveAccessToken', () {
test('should call FlutterSecureStorage to save token', () async {
// arrange
when(() =>
mockSecureStorage.write(
key: savedToken, value: json.encode(tAccessToken))).thenAnswer(
(invocation) => Future<void>.value());
//act
dataSource.saveAccessToken(tAccessToken);
// assert
final expectedJsonString = json.encode(tAccessToken.toJson());
verify(() => mockSecureStorage.write(
key: savedToken, value: expectedJsonString));
});
});
});
}
fixtures_reader.dart
import 'dart:io';
String fixture(String name) => File('test/fixtures/$name').readAsStringSync();
美好的一天!
我需要测试 flutter secure storage 的一些功能。例如storage.saveAccessToken
我已经制作了 MockFlutterStorage 来模拟存储中的保存,但是它不起作用。
这是我的代码:
@GenerateMocks([mockFlutterSecureStorage.FlutterSecureStorage])
void main() {
group('#accessToken', () {
test('Save accessToken in a storage', () async {
final mockFlutterSecureStorage = MockFlutterSecureStorage();
String accessToken = 'a1';
final storage = SecureStorage();
when(mockFlutterSecureStorage.write(
key: 'accessToken', value: accessToken))
.thenAnswer((value) async => {
await storage.saveAccessToken(accessToken);
});
expect(storage.accessToken, 'a1');
});
});
}
应该添加新的答案来举个例子。请注意,我正在使用 mocktail。解释一下这个想法我觉得够了
user_secure_data_source.dart
import 'dart:convert';
import 'package:flutter_app/core/error/exception.dart';
import 'package:flutter_app/features/auth/data/models/models.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
abstract class UserSecureDataSource {
Future<AccessTokenModel> getSavedAccessToken();
void saveAccessToken(AccessTokenModel accessToken);
}
const savedToken = 'SAVED_TOKEN';
class UserSecureDataSourceImpl implements UserSecureDataSource {
UserSecureDataSourceImpl({required this.secureStorage});
final FlutterSecureStorage secureStorage;
@override
Future<AccessTokenModel> getSavedAccessToken() async {
final jsonString = await secureStorage.read(key: savedToken);
if (jsonString != null) {
return Future.value(AccessTokenModel.fromJson(json.decode(jsonString)));
} else {
throw NotFoundSavedTokenSecureException();
}
}
@override
Future<void> saveAccessToken(AccessTokenModel accessToken) async {
return secureStorage.write(
key: savedToken, value: json.encode(accessToken));
}
}
user_secure_data_source_test.dart
import 'dart:convert';
import 'package:flutter_app/core/error/exception.dart';
import 'package:flutter_app/features/auth/data/datasources/user_secure_data_source.dart';
import 'package:flutter_app/features/auth/data/models/models.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:test/test.dart';
import 'package:mocktail/mocktail.dart';
import '../../../../fixtures/fixtures_reader.dart';
class MockFlutterSecureStorage extends Mock implements FlutterSecureStorage {}
void main() {
late UserSecureDataSourceImpl dataSource;
late MockFlutterSecureStorage mockSecureStorage;
final tAccessToken = AccessTokenModel.fromJson(
json.decode(fixture('access_token_model.json')));
setUp(() {
mockSecureStorage = MockFlutterSecureStorage();
dataSource = UserSecureDataSourceImpl(secureStorage: mockSecureStorage);
});
group('UserSecureDataSourceIml', () {
group('getSavedAccessToken', () {
test(
'should return AccessTokenModel from FlutterSecureStorage when there is one the saved',
() async {
// arrange
when(() => mockSecureStorage.read(key: savedToken))
.thenAnswer((_) async => fixture('access_token_model.json'));
// act
final result = await dataSource.getSavedAccessToken();
//assert
verify(() => mockSecureStorage.read(key: savedToken));
expect(result, equals(tAccessToken));
});
test(
'should throw a NotFoundSavedTokenSecureException when is not saved token',
() async {
// arrange
when(() => mockSecureStorage.read(key: savedToken))
.thenAnswer((_) async => null);
// act
final call = dataSource.getSavedAccessToken;
//assert
expect(() => call(), throwsA(isA<NotFoundSavedTokenSecureException>()));
});
});
group('saveAccessToken', () {
test('should call FlutterSecureStorage to save token', () async {
// arrange
when(() =>
mockSecureStorage.write(
key: savedToken, value: json.encode(tAccessToken))).thenAnswer(
(invocation) => Future<void>.value());
//act
dataSource.saveAccessToken(tAccessToken);
// assert
final expectedJsonString = json.encode(tAccessToken.toJson());
verify(() => mockSecureStorage.write(
key: savedToken, value: expectedJsonString));
});
});
});
}
fixtures_reader.dart
import 'dart:io';
String fixture(String name) => File('test/fixtures/$name').readAsStringSync();