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();