How should I test a Future in Dart?
As an alternative, here's what I've been doing. It's similar to the answers above:
test('get by keys', () {
Future future = asyncSetup().then((_) => store.getByKeys(["hello", "dart"]));
future.then((values) {
expect(values, hasLength(2));
expect(values.contains("world"), true);
expect(values.contains("is fun"), true);
});
expect(future, completes);
});
I get a reference to the future, and put all my expect statements inside the then
call. Then, I register a expect(future, completes)
to ensure it actually completes.
Full example of how to test with the completion
matcher is as follows.
import 'package:unittest/unittest.dart';
class Compute {
Future<Map> sumIt(List<int> data) {
Completer completer = new Completer();
int sum = 0;
data.forEach((i) => sum += i);
completer.complete({"value" : sum});
return completer.future;
}
}
void main() {
test("testing a future", () {
Compute compute = new Compute();
Future<Map> future = compute.sumIt([1, 2, 3]);
expect(future, completion(equals({"value" : 6})));
});
}
The unit test runner might not complete before this code completes. So it would seem that the unit test executed correctly. With Future
s that might take longer periods of time to complete the proper way is to utilize completion
matcher available in unittest package.
/**
* Matches a [Future] that completes succesfully with a value that matches
* [matcher]. Note that this creates an asynchronous expectation. The call to
* `expect()` that includes this will return immediately and execution will
* continue. Later, when the future completes, the actual expectation will run.
*
* To test that a Future completes with an exception, you can use [throws] and
* [throwsA].
*/
Matcher completion(matcher) => new _Completes(wrapMatcher(matcher));
One would be tempted to do the following which would be incorrect way of unit testing a returned Future in dart. WARNING: below is an incorrect way to test Futures.
import 'package:unittest/unittest.dart';
class Compute {
Future<Map> sumIt(List<int> data) {
Completer completer = new Completer();
int sum = 0;
data.forEach((i) => sum+=i);
completer.complete({"value":sum});
return completer.future;
}
}
void main() {
test("testing a future", () {
Compute compute = new Compute();
compute.sumIt([1, 2, 3]).then((Map m) {
Expect.equals(true, m.containsKey("value"));
Expect.equals(6, m["value"]);
});
});
}