Developing with Flutter Master Channel

Flutter is starting to support null-safe Dart language with its latest releases. This comes with new syntax as well as SDK changes which may break your current project during compilation. If you have seen a similar message to this during build, Error: The non-abstract class '_TestFairyClientHttpRequest' is missing implementations for these members: HttpClientRequest.abort, it means your code base is not ready for Flutter’s breaking changes. Let’s fix this together.

Upgrading to null-safe Dart

Before fixing our code, we must follow the official Dart null-safety migration guide to make sure our environment is ready for the upgrade. We highly suggest you also incorporate dartfmt as well to ensure a consistent styling in your code base.

Fixing Missing Implementations

Some classes in Dart and Flutter SDK may now have new methods added to them. If one of your classes inherit these, you will encounter an error which probably looks like below:

../pub.dartlang.org/testfairy-1.x.y/lib/src/network_logging.dart:253:7: 
            Error: The non-abstract class '_TestFairyClientHttpRequest' is missing implementations for these members:

     - HttpClientRequest.abort

    Try to either
     - provide an implementation,
     - inherit an implementation from a superclass or mixin,
     - mark the class as abstract, or
     - provide a 'noSuchMethod' implementation.

    class _TestFairyClientHttpRequest implements HttpClientRequest {
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    org-dartlang-sdk:///third_party/dart/sdk/lib/_http/http.dart:2045:8: Context: 'HttpClientRequest.abort' is defined here.
      void abort([Object? exception, StackTrace? stackTrace]);
           ^^^^^

This error tells us one of our classes inheriting from HttpClientRequest requires abort() to be implemented. We need to imitate the exact method signature for this and luckily, the error message points to the correct file we need to copy our method from.

Checking the source code, we locate this new method and copy its signature to our own implementation.

@Since("2.10")
void abort([Object? exception, StackTrace? stackTrace]);

As you can see, this method is only supported after Dart SDK 2.10 and incorporates explicitly nullable types for its optional arguments.

Copy it to your derived class and make sure it is annotated with the @override keyword.

@Since("2.10")
@override
void abort([Object? exception, StackTrace? stackTrace]) {
    // your implementation
}

If you repeat these steps for each error in your build output, eventually your project will compile and the issue will be resolved.

TestFairy Plugin Compatibility

These kind of migrations are not backward compatible when new Dart syntax is used in the added code. Right now, Flutter only includes this changes in its master channel which is not officially considered as stable. In order to support both the old and new SDKs, we ship our plugin with migration steps commented out. This will change once Flutter releases these additions under its stable channel. For people who can’t wait, here are the steps to make TestFairy work again.

In a nutshell, you must clone this repo and use it as an offline dependency instead of the published version in pub.

1. Clone this repo.

2. Use the following code to include the clone as an offline dependency (assuming both projects reside in the same directory as siblings).

dependencies:
  testfairy:
    path: ../testfairy-flutter # or "./testfairy-flutter" if your clone is inside your main project as a child directory

3. Launch a terminal and run the following commands.

cd path/to/testfairy-flutter
sed "s/Modern Flutter \*\*/\//" lib/src/network_logging.dart > lib/src/network_logging.dart
sed "s/\*\* Modern Flutter/\//" lib/src/network_logging.dart > lib/src/network_logging.dart

4. Checkout testfairy-flutter to your VCS without including its .git directory.

5. When there is a new update in this repo, delete testfairy-flutter and retry the steps.