[Flutter] Riverpod(hooks riverpod)를 사용하여 Widget Test에서Provider의 쓰기 방법을 덮어쓰는 견본

☆ 내가 처음으로 투고한 기사야.틀리면☆

컨디션

  • Dart: 2.12.0
  • Flutter: 1.26.0-17.5.pre
  • hooks_riverpod: 0.12.4
  • freezed: 0.12.7
  • 이 문장의 목적


    공식 Docts의 Testing 페이지에 데이터 파일이widget 정의와Test를 하는 예가 쓰여 있지만 일반적인 경우 다른 파일로 많이 쓴다.
    Riverpod에서는 테스트 시 Provider의 구현을 덮어쓸 수 있습니다.자기가 위젯 테스트를 쓸 때 착각해서 테스트가 통과하지 못하고 생각에 잠겼기 때문에 메모로 적어놨어요.

    자기가 저지른 잘못


    Widget Test에서는 Test를 쓰는 것과 같은 데이터 파일에 정의된 Provider를 호출하는 줄 알았지만, 결국 useProvider 등 파일의 Provider를 호출했다.[1]

    Widget 정의 및 Test 견본을 작성합니다.


    여기서부터 샘플 코드를 쓰기 시작합니다.참고가 됐으면 좋겠어요.
    state/auth/user/auth_state.dart
    
    abstract class AuthState with _$AuthState {
      const factory AuthState({
        @Default(false) bool isAuthenticated
      }) = _AuthState;
    }
    
    class AuthStateNotifier extends StateNotifier<AuthState> {
      AuthStateNotifier() : super(const AuthState());
    
      AuthStateNotifier.withDefaultValue({ bool isAuthenticated})
          : super(AuthState(isAuthenticated: isAuthenticated));
    
      set isAuthenticated(bool authenticationState) {
        state = state.copyWith(isAuthenticated: authenticationState);
      }
    
      bool get isAuthenticated {
        return state.isAuthenticated;
      }
    }
    
    lib/middleware/auth_middleware.dart
    final authStateNotifierProvider =
        StateNotifierProvider((_) => AuthStateNotifier());
    
    class AuthMiddleWare extends HookWidget {
      const AuthMiddleWare(this.amplifyApi);
    
      final AmplifyApiInterface amplifyApi;
    
      
      Widget build(BuildContext context) {
        final authStateNotifier = useProvider(authStateNotifierProvider);
    
        if (authStateNotifier.isAuthenticated) {
          return HomeView();
        } else {
          return StartupView();
        }
      }
    }
    
    Test code는 바로 이런 느낌입니다.
    test/widget/middleware/auth_middleware_test.dart
    void main() {
      group('AuthMiddleware', () {
        testWidgets('should go to HomeView Page when authenticated',
            (WidgetTester tester) async {
          await tester.pumpWidget(
            ProviderScope(
    	  // ここでProviderの実装を上書き。authStateNotifierProviderを呼ぶことに注意。
              overrides: [
                authStateNotifierProvider.overrideWithValue(
                  AuthStateNotifier.withDefaultValue(isAuthenticated: true),
                ),
              ],
              child: MaterialApp(
                home: AuthMiddleWare(),
              ),
            ),
          );
    
          expect(find.byType(HomeView), findsOneWidget);
        });
      });
    }
    
    각주
    곰곰이 생각해 보면 당연한 거야...↩︎

    좋은 웹페이지 즐겨찾기