1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】ユニットテストを作成する

1
Posted at

前回記事のテストコードです。

test/application/usecases/get_user_test.dart

test/application/usecases/get_user_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:sampleapp/application/usecases/get_user.dart';
import 'package:sampleapp/core/result/app_result.dart';
import 'package:sampleapp/domain/entities/repositories/user_repository.dart';
import 'package:sampleapp/domain/entities/user.dart';

class MockUserRepository implements UserRepository{
  @override
  Future<AppResult<User>> fetchUser() async{
    return const AppSuccess(
      User(name:'Test User'),
    );
  }
}

class MockFailureUserReposiotry implements UserRepository{
  @override
  Future<AppResult<User>> fetchUser() async{
    return const AppFailure(
      'ユーザー取得に失敗しました',
    );
  }
}

void main(){
  group('GetUser',(){
    test('RepositoryからUserを取得できる', ()async{
      final repository = MockUserRepository();
      final getUser = GetUser(repository);
      final result = await getUser();
      expect(result, isA<AppSuccess<User>>());
      final success = result as AppSuccess<User>;
      expect(success.data.name,'Test User');
    });
    test('Repositoryが失敗した場合はFailureを返す',()async{
      final repository = MockFailureUserReposiotry();
      final getUser = GetUser(repository);
      final result = await getUser();
      expect(result, isA<AppFailure<User>>());
      final failure = result as AppFailure<User>;
      expect(
        failure.message,
        'ユーザー取得に失敗しました',
      );
    });
  });
}

test/core/result/app_result_test.dart

test/core/result/app_result_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:sampleapp/core/result/app_result.dart';

void main(){
  group('AppSuccess',(){
    test('dataを保持する',(){
      const result = AppSuccess<String>('success');
      expect(result.data,'success');
      expect(result, isA<AppSuccess<String>>());
    });
  });
  group('AppFailure',(){
    test('messageを保持する',(){
      const result = AppFailure<String>('error');
      expect(result.message,'error');
      expect(result,isA<AppFailure<String>>());
    });
  });
}

test/data/repositories/user_repository_impl_test.dart

test/data/repositories/user_repository_impl_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:sampleapp/core/result/app_result.dart';
import 'package:sampleapp/data/repositories/user_repository_impl.dart';
import 'package:sampleapp/domain/entities/user.dart';

void main(){
  group('UserRepositoryImpl',(){
    test('ユーザーを取得するとAppSuccessを返す',()async{
      final repository = UserRepositoryImpl();
      final result = await repository.fetchUser();
      expect(result, isA<AppSuccess<User>>());
      final success = result as AppSuccess<User>;
      expect(success.data.name,'taro');
    });
  });
}

test/presentation/pages/home_page_test.dart

test/presentation/pages/home_page_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import 'package:sampleapp/core/result/app_result.dart';
import 'package:sampleapp/domain/entities/user.dart';
import 'package:sampleapp/presentation/pages/home_page.dart';
import 'package:sampleapp/presentation/providers/user_provider.dart';

void main() {
  group('HomePage', () {
    testWidgets(
      'ユーザー取得中はローディングが表示される',
          (tester) async {
        await tester.pumpWidget(
          ProviderScope(
            overrides: [
              userProvider.overrideWith(
                    (ref) async {
                  await Future.delayed(
                    const Duration(seconds: 1),
                  );

                  return const AppSuccess(
                    User(name: 'Test User'),
                  );
                },
              ),
            ],
            child: const MaterialApp(
              home: HomePage(),
            ),
          ),
        );

        expect(
          find.byType(CircularProgressIndicator),
          findsOneWidget,
        );
      },
    );

    testWidgets(
      'ユーザー取得に成功するとユーザー名が表示される',
          (tester) async {
        await tester.pumpWidget(
          ProviderScope(
            overrides: [
              userProvider.overrideWith(
                    (ref) async {
                  return const AppSuccess(
                    User(name: 'Test User'),
                  );
                },
              ),
            ],
            child: const MaterialApp(
              home: HomePage(),
            ),
          ),
        );

        await tester.pump();

        expect(
          find.text('こんにちは、Test Userさん!'),
          findsOneWidget,
        );
      },
    );

    testWidgets(
      'AppFailureの場合はエラーメッセージが表示される',
          (tester) async {
        await tester.pumpWidget(
          ProviderScope(
            overrides: [
              userProvider.overrideWith(
                    (ref) async {
                  return const AppFailure(
                    'ユーザー取得に失敗しました',
                  );
                },
              ),
            ],
            child: const MaterialApp(
              home: HomePage(),
            ),
          ),
        );

        await tester.pump();

        expect(
          find.text('ユーザー取得に失敗しました'),
          findsOneWidget,
        );
      },
    );

    testWidgets(
      'Provider自体がExceptionになった場合は予期しないエラーが表示される',
          (tester) async {
        await tester.pumpWidget(
          ProviderScope(
            overrides: [
              userProvider.overrideWith(
                    (ref) async {
                  throw Exception('Unexpected error');
                },
              ),
            ],
            child: const MaterialApp(
              home: HomePage(),
            ),
          ),
        );

        await tester.pump();

        expect(
          find.textContaining('予期しないエラー:'),
          findsOneWidget,
        );
      },
    );
  });
}

test/presentation/providers/user_provider_test.dart

test/presentation/providers/user_provider_test.dart
import 'package:sampleapp/core/result/app_result.dart';
import 'package:sampleapp/data/repositories/user_repository_impl.dart';
import 'package:sampleapp/domain/entities/repositories/user_repository.dart';
import 'package:sampleapp/domain/entities/user.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:sampleapp/presentation/pages/home_page.dart';
import 'package:sampleapp/presentation/providers/user_provider.dart';

class MockUserRepository implements UserRepositoryImpl{
  Future<AppResult<User>> fetchUser() async{
    return const AppSuccess(
      User(name: 'Provider Test User'),
    );
  }
}

class MockFailureUserRepository implements UserRepository{
  @override
  Future<AppResult<User>> fetchUser()async{
    return const AppFailure(
      'Provider Test Error',
    );
  }
}

void main() {
  group('userRepositoryProvider', () {
    test('UserRepositoryを取得できる', () {
      final container = ProviderContainer();

      addTearDown(container.dispose);

      final repository = container.read(
        userRepositoryProvider,
      );

      expect(repository, isA<UserRepository>());
    });
  });

  group('getUserProvider', () {
    test('GetUserを取得できる', () {
      final container = ProviderContainer(
        overrides: [
          userRepositoryProvider.overrideWith(
                (ref) => MockUserRepository(),
          ),
        ],
      );

      addTearDown(container.dispose);

      final getUser = container.read(
        getUserProvider,
      );

      expect(getUser, isNotNull);
    });
  });

  group('userProvider', () {
    test('ユーザー取得に成功する', () async {
      final container = ProviderContainer(
        overrides: [
          userRepositoryProvider.overrideWith(
                (ref) => MockUserRepository(),
          ),
        ],
      );

      addTearDown(container.dispose);

      final result = await container.read(
        userProvider.future,
      );

      expect(result, isA<AppSuccess<User>>());

      final success = result as AppSuccess<User>;

      expect(
        success.data.name,
        'Provider Test User',
      );
    });

    test('ユーザー取得に失敗する', () async {
      final container = ProviderContainer(
        overrides: [
          userRepositoryProvider.overrideWith(
                (ref) => MockFailureUserRepository(),
          ),
        ],
      );

      addTearDown(container.dispose);

      final result = await container.read(
        userProvider.future,
      );

      expect(result, isA<AppFailure<User>>());

      final failure = result as AppFailure<User>;

      expect(
        failure.message,
        'Provider Test Error',
      );
    });
  });
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?