dimanche 11 avril 2021

Why does a Dart Future affect a Flutter unit test?

If I add to a simple unit test the loading of an asset file in the constructor

import 'package:flutter/services.dart' show rootBundle;

Future<String> loadAsset(String path) async {
  return await rootBundle.loadString(path);
}

class Counter {
  int value = 0;
  void increment() => value++;
  void decrement() => value--;

  Counter() {
    loadAsset('assets/hello.txt').then((dynamic output) {
      print('$output');
    });
  }
}

without modifying the Counter class

import 'package:test/test.dart';
import 'package:counter/counter.dart';

void main() {
  test('Counter value should be incremented', () {
    final counter = Counter();

    counter.increment();

    expect(counter.value, 1);
  });
}

then I'm expecting that the test will continue to pass just the same.

I do not know whether

  1. the print statement will execute before or after counter.increment(),
  2. nor whether it will run before or after expect(counter.value, 1),

but that doesn't matter, because the counter will be initialized before the first line of the constructor runs, and the expect can only run after increment() would have completed.

That's not the case. I get:

> flutter test test/counter_test.dart
Running "flutter pub get" in counter...                         1,010ms
00:03 +0 -1: Counter value should be incremented [E]
  Null check operator used on a null value
  package:flutter/src/services/asset_bundle.dart 225:39  PlatformAssetBundle.load
  ...
  test/counter_test.dart 7:21                            main.<fn>
  
00:03 +0 -1: Some tests failed.

Why does a Dart Future interfere with a Flutter test?

Update

OK, now that I've typed the question, I see the problem. The instance final Counter is not actually yet initialized when the increment and the expect statements run. That's by design, since the result of await could matter for the object.

Still, is there an inherent flaw in await-ing in a constructor (that's used in a test)? How would you rewrite this test if you want to initialize some data from an asset?

Aucun commentaire:

Enregistrer un commentaire