I'm writing widget tests for a Flutter app. I have a DataTable
that I'm trying to test, but when I try to find a specific DataRow
by the ValueKey
I've assigned, I get the error:
Expected: exactly one matching node in the widget tree
Actual: _KeyFinder:<zero widgets with key [<'row_1685964365554x393824037782945800'>]>
Which: means none were found but one was expected
To diagnose the issue, I simplified the test by creating a plain DataTable in my test file. Here is my code:
import 'package:flutter_test/flutter_test.dart';
class Item {
final String id;
final String name;
final String type;
Item({
required this.id,
required this.name,
required this.type,
});
}
const kKeyValueToFind = "1685964365554x393824037782945800";
List<Item> _createItems() {
return <Item>[
Item(
id: kKeyValueToFind,
name: "kimchee",
type: "food",
),
Item(
id: "1679537663980x853624879356837900",
name: "Pizza dough",
type: "food",
),
Item(
id: "1678726754135x305030564311466000",
name: "Guava juice",
type: "drink",
)
];
}
Widget _createTestWidget(List<Item> items) {
return Builder(
builder: (BuildContext context) {
return MaterialApp(
home: Scaffold(
body: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('col1')),
DataColumn(label: Text('col2')),
],
rows: items
.map(
(e) => DataRow(
cells: <DataCell>[
DataCell(
Text(
key: ValueKey('cell1_${e.id}'),
e.name,
),
),
DataCell(
Text(
key: ValueKey('cell2_${e.id}'),
e.type,
),
),
],
key: ValueKey('row_${e.id}'),
),
)
.toList(),
),
),
);
},
);
}
void main() {
late List<Item> items;
setUp(() {
items = _createItems();
});
group('DataTable key test', () {
testWidgets('Should find a DataTable row by id', (WidgetTester tester) async {
// arrange
await tester.pumpWidget(_createTestWidget(items));
debugDumpApp();
// act
var rowFinder = find.byKey(const Key('row_$kKeyValueToFind'));
// assert
expect(rowFinder, findsOneWidget);
});
});
}
You can also view it in DartPad.
Similar to my initial tests, running debugDumpApp()
shows the widget tree without the specified key for any DataRows. You can see the output of the debugDumpApp()
call as part of my related gist, here.
I've searched SO, but haven't found any questions that deal with this issue or help me resolve it. The closest posts I found are probably this, this, and this.
Can anyone see what I'm doing wrong? Or do you think this is a bug with Flutter? I found this bug report from April 2020 that was closed without being resolved, and it seems to deal with this exact issue.
I'm hoping it's just something I'm doing wrong, as that will be a lot easier to fix.