Assertions in Dart class constructors
Not to be confused with assertions done in testing, class constructor assertions are a great way to prevent errors in your Dart code. They can be used to check that the values passed to a constructor are valid as per application logic, for example, ensuring that an integer passed is within a given range.
To use an assertion in a class constructor, you simply add an
assert()
statement to the constructor body (examples below). The assert
statement takes a boolean expression as its argument, and if the expression evaluates to false
, the constructor throws an AssertionError
exception. By default, a generic exception message will be shown, but if a second parameter is passed to assert
then that will be used as the error message instead.Here is a contrived example of a simple class constructor with an assertion:
class Person {
Person(this.name) : assert(name.isNotEmpty);
final String name;
}
This constructor will throw an
AssertionError
exception if the name
parameter is empty.Here is an example of how to use the
Person
class:Person person = Person('Luke');
// This will work fine.
print(person.name);
// This will throw an AssertionError exception.
var emptyPerson = Person('');
Assertions can be used to check all sorts of things in class constructors. For example, you can use them to check that:
- The values passed to the constructor are within a certain range.
- The values passed to the constructor are of the correct type.
- In cases where arguments A and B are both not mandatory, at least one has a value
- Think of an Avatar widget, where you could either have a letter or an image
Note however, that assertions only happen in development code and do not run in production code at all (see here).
Things to consider
- Don't use assertions to perform complex operations. Assertions are meant to be simple checks, not full-blown validation functions.
- Don't use assertions to replace unit tests. Assertions are a good way to catch potential errors early on, but they are not a substitute for unit tests
Examples of usages in Material Design widgets
Flutter's Material Design widgets make extensive use of assertions in their constructors which are really good at moaning at you, especially in the early days of learning Flutter. For example, the
Container
widget has an assertion to check that if you pass decoration
, that you also do not set a color
.container.dart
class Container extends StatelessWidget {
Container({
super.key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(decoration != null || clipBehavior == Clip.none),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'To provide both, use "decoration: BoxDecoration(color: color)".',
);
...
}