Is it possible to write a unit test that verifies that the maxLines property of a TextFormField is set correctly. I can not find a way to access the property:
i create a TextFormField
final field = TextFormField(
initialValue: "hello",
key: Key('textformfield'),
maxLines: 2,
);
then in the test i get access to the form field with tester.widget
final formfield =
await tester.widget<TextFormField>(find.byKey(Key('textformfield')));
but since the maxLines property is passed to the Builder which returns a Textfield, how can i get access to the textfield.
Or is there an completely other ways to verify this?
I don't know if this is a good solution but as i set the value of my TextFormField i can find the EditableText widget directly. of this widget i can find test the property maxLines.
final EditableText formfield =
tester.widget<EditableText>(find.text('testvalue'));
expect(formfield.maxLines, 2);
The reason you can't see properties such as maxLines
or maxLength
is because they belong to the TextField
class.
Take a look at the documentation of the TextFormField
constructor in the source file:
/// Creates a [FormField] that contains a [TextField].
///
/// When a [controller] is specified, [initialValue] must be null (the
/// default). If [controller] is null, then a [TextEditingController]
/// will be constructed automatically and its `text` will be initialized
/// to [initialValue] or the empty string.
///
/// For documentation about the various parameters, see the [TextField] class
/// and [new TextField], the constructor.
Unfortunately you can't retrieve the TextField
object from a TextFormField
, you'll have to find the TextField
object through a finder instead.
Let's assume you have a form with 2 fields - first name and last name. What you need to do is find all widgets of type TextField
, add them to a list and then you can loop through each element of the list and run your test. Here's an example:
testWidgets('Form fields have the correct maximum length and number of lines',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: Form(
child: Column(
children: <Widget>[
TextFormField(
key: Key('first_name'),
decoration: InputDecoration(hintText: 'First name'),
maxLines: 1,
maxLength: 50,
obscureText: true,
),
TextFormField(
key: Key('last_name'),
decoration: InputDecoration(hintText: 'Last name'),
maxLines: 1,
maxLength: 25,
),
],
),
),
),
));
List<TextField> formFields = List<TextField>();
find.byType(TextField).evaluate().toList().forEach((element) {
formFields.add(element.widget);
});
formFields.forEach((element) {
expect(element.maxLines, 1);
switch (element.decoration.hintText) {
case 'First name':
expect(element.maxLength, 50);
break;
case 'Last name':
expect(element.maxLength, 25);
break;
}
});
});
If you only one field, you could do this instead:
TextField textField = find.byType(TextField).evaluate().first.widget as TextField;
expect(textField.maxLines, 1);
expect(textField.maxLength, 50);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With