skip to Main Content

I’m trying to test a button, but it keeps giving this error

═╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following StateError was thrown running a test:
Bad state: No element

When the exception was thrown, this was the stack:
#0      Iterable.single (dart:core/iterable.dart:670:25)
#1      WidgetController.element (package:flutter_test/src/controller.dart:394:30)
#2      WidgetController.ensureVisible (package:flutter_test/src/controller.dart:1567:73)
#3      main.<anonymous closure> (file:///C:/Users/user/Documents/app/test/widgests/button_test.dart:9:18)
#4      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:170:29)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

The test description was:
  Test button
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: Test button

✖ Test button

Exited (1)
//file button_test.dart
// ignore_for_file: depend_on_referenced_packages

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Test button', (tester) async {
    final btnFinder = find.byKey(const Key('button'));
    await tester.ensureVisible(btnFinder);
    await tester.tap(btnFinder);
    await tester.pumpAndSettle();
  });
}

//file button.dart
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';

import 'inactivity/universal_tap_handler.dart';

class Button extends StatelessWidget {
  const Button({
    required this.label,
    this.onTap,
    this.icon,
    this.height = 50,
    this.width,
    this.backgroundColor,
    super.key,
  });

  final void Function()? onTap;
  final String label;
  final Widget? icon;
  final double height;
  final double? width;
  final Color? backgroundColor;

  @override
  Widget build(BuildContext context) {

    return SizedBox(
      key: const Key('button'),
      height: height,
      width: width ?? double.infinity,
      child: Card(
        elevation: 5,
        color: const Color(0xFFC2A79F),
        margin: const EdgeInsets.all(0),
        child: UniversalTapHandler(
          onTap: onTap!,
          child: Row(
            children: [
              // Label
              Expanded(
                child: Center(
                  child: AutoSizeText(
                    label.toUpperCase(),
                    maxLines: 1,
                    textAlign: TextAlign.left,
                    style: const TextStyle(
                      fontSize: 16,
                      color: Color(0xFFEDE0D2),
                      fontWeight: FontWeight.w800,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

    // file UniversalTapHandler
    class UniversalTapHandler extends RawGestureDetector {
  UniversalTapHandler({
    required GestureTapCallback onTap,
    required Widget child,
    super.key,
  }) : super(
          gestures: <Type, GestureRecognizerFactory>{
            _UniversalPointerHandler: GestureRecognizerFactoryWithHandlers<_UniversalPointerHandler>(
              () => _UniversalPointerHandler(),
              (instance) {
                instance.onTap = onTap;
              },
            ),
          },
          child: child,
        );
}

class _UniversalPointerHandler extends TapGestureRecognizer {
  @override
  void rejectGesture(int pointer) {
    acceptGesture(pointer);
  }
}

2

Answers


  1. It looks like you’re missing a await tester.pumpWidget(Button()); at the very beginning of your test. If no widget is loaded in the tree, find.byKey will fail.

    Login or Signup to reply.
  2. You haven’t setup(pump) the widget to test on. It will be

    void main() {
      testWidgets('Test button', (tester) async {
        await tester.pumpWidget(
          MaterialApp(
            home: Scaffold(
              body: Button(
                label: 'Test',
                onTap: () {},
              ),
            ),
          ),
        );
        final btnFinder = find.byKey(const Key('button'));
        expect(btnFinder, findsOneWidget); // check if button is present
        await tester.ensureVisible(btnFinder);
        await tester.tap(btnFinder);
        await tester.pumpAndSettle();
      });
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search