mirage
mirage

Reputation: 177

No material widget found in test

I am getting the No material widget found error when I run the following test, even though I am wrapping it in a MaterialApp. Any pointers to why that is?

void main() {
  final mockExam = examMocks[0];
  Widget createGridItem() => Provider<ExamInformation>.value(
        value: ExamInformation(
            examSpecifications: mockExam.examSpecifications,
            examImage: mockExam.examImage,
            questionList: mockExam.questionList),
        child: ExamGridItem(),
      );

  testWidgets('Exam grid item displays Footer', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: createGridItem()));

    final gridItemFooterFinder = find.byType(Footer);
    expect(gridItemFooterFinder, findsOneWidget);
  });
}

Detailed error log:

The following assertion was thrown building _InkResponseStateWidget(gestures: [tap], mouseCursor:
null, BoxShape.circle, dirty, state: _InkResponseState#3ef96):
No Material widget found.
_InkResponseStateWidget widgets require a Material widget ancestor.
In material design, most widgets are conceptually "printed" on a sheet of material. In Flutter's
material library, that material is represented by the Material widget. It is the Material widget
that renders ink splashes, for instance. Because of this, many material library widgets require that
there be a Material widget in the tree above them.
To introduce a Material widget, you can either directly include one, or use a widget that contains
Material itself, such as a Card, Dialog, Drawer, or Scaffold.

The specific widget that could not find a Material ancestor was:
  _InkResponseStateWidget
The ancestors of this widget were:
  ...
  InkResponse
  Positioned
  Stack
  GridTile
  Consumer<ExamInformation>
  ...

Upvotes: 3

Views: 1352

Answers (2)

Sanjay Bharwani
Sanjay Bharwani

Reputation: 4749

Faced the same problem writing widget test.

The error says it all.

The following assertion was thrown building ListTile(title: Text, trailing: CustomIcon, onTap:
  Closure: () => void, selectedTileColor: Color(0xfff3f3f3), dirty):
  No Material widget found.
  ListTile widgets require a Material widget ancestor within the closest LookupBoundary.

My widget was simple widget wrapping ListTile and as you see the error says

ListTile widgets require a Material widget ancestor within the closest LookupBoundary

Widget works perfectly fine when used on the real page, as the page is built around Scaffold which provides Material widget ancestor to the ListTile which is part of my custom widget. And this is also explained in the error

     ListTile widgets require a Material widget ancestor within the closest LookupBoundary.
 In Material Design, most widgets are conceptually "printed" on a sheet of material. In Flutter's material library, that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. Because of this, many material library widgets require that there be a Material widget in the tree above them.
    To introduce a Material widget, you can either directly include one, or use a widget that contains
    Material itself, such as a Card, Dialog, Drawer, or Scaffold.

Solution

Before Code

await $.pumpWidgetAndSettle(
      wrapWithApp(
        child: widgetUnderTest)

After Code

await $.pumpWidgetAndSettle(
      wrapWithApp(
        child: Material(child: widgetUnderTest))

So basically wrapped my widgetUnderTest in Material.

References No Material widget found

Upvotes: 1

TheMisir
TheMisir

Reputation: 4279

You have to put your widget inside Material widget.

Example:

Material(child: InkWell())

The widget causing this error was shown in error description:

  InkResponse
  Positioned
  Stack
  GridTile
  Consumer<ExamInformation>

Upvotes: 1

Related Questions