Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I test a Future in Dart?

How can one test a method that returns Future before the test runner completes? I have a problem where my unit test runner completes before the asynchronous methods are completed.

like image 354
adam-singer Avatar asked Dec 03 '12 07:12

adam-singer


People also ask

How do you find the future value in darts?

In order to get the value, we need to use the await keyword. var myfut2 = await Future. value(14); print(myfut2); We create another future and wait for its result with the await keyword.

How do you wait for Future to complete Dart?

To prevent multiple awaits, chaining futures in . then(), you can simply use Future. wait([]) that returns an array of results you were waiting for. If any of those Futures within that array fails, Future.

How do you test a Dart file?

A single test file can be run just using dart test path/to/test. dart (as of Dart 2.10 - prior sdk versions must use pub run test instead of dart test ). Many tests can be run at a time using dart test path/to/dir . It's also possible to run a test on the Dart VM only by invoking it using dart path/to/test.

How do you deal with Future in Flutter?

There are two different ways to execute a Future and utilize the value it returns. If it returns any whatsoever. The most well-known way is to await on the Future to return. For everything to fall into work, your function that is calling the code must be checked async.


1 Answers

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 Futures 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"]);     });   }); } 
like image 193
adam-singer Avatar answered Oct 10 '22 03:10

adam-singer