Writing a unit test for asynchronous code in Dart Test

dart, dart-async, dart-unittest

Solution

I just re-read your question, and I realize I was answering sort of the wrong question...

I believe you're using `expectAsync` incorrectly. `expectAsync` is used to wrap a callback with N parameters and ensure that it ran `count` times (default 1).

`expectAsync` will ensure that any exceptions are caught by the test itself and are returned. It does not actually run any expectations by itself (bad nomenclature.)

What you want is just:

database.AddMessage(null).then(
  (value) { /* Don't do anything! No expectations = success! */ },
  onError: (err) { 
    // It's enough to just fail!
    fail('error !');
  }
);

or if you need to ensure that the test completed to some particular value:

database.AddMessage(null).then(
  expectAsync1((value) { /* Check the value in here if you want. */ }),
  onError: (err) { 
    // It's enough to just fail!
    fail('error !');
  }
);

Another way of doing this is to use the `completes` matcher.

// This will register an asynchronous expectation that will pass if the
// Future completes to a value.
expect(database.AddMessage(null), completes);

or to test for an exception:

// Likewise, but this will only pass if the Future completes to an exception.
expect(database.AddMessage(null), throws);

If you want to check the completed value, you could do as follows:

expect(database.AddMessage(null).then((value) {
  expect(value, isNotNull);
}), completes);

See:

- http://api.dartlang.org/docs/bleeding_edge/matcher.html#completes

- http://api.dartlang.org/docs/bleeding_edge/unittest.html#expectAsync0

- http://www.dartlang.org/articles/dart-unit-tests/#asynchronous-tests

Problem

After reading the Unit Testing with Dart somehow I'm still can not understand how to use it with `Future`s. For example: ``` void main() { group('database group', () { setUp(() { // Setup }); tearDown(() { // TearDown }); test('open connection to local database', () { DatabaseBase database = null; expect(database = new MongoDatabase("127.0.0.8", "simplechat-db"), isNotNull); database.AddMessage(null).then((e) { expectAsync1(e) { // All ok } }, onError: (err) { expectAsync1(bb) { fail('error !'); } }); }); // Add more tests here }); } ``` So in the test I create an instance of base abstract class `DatabaseBase` with some parameters to actual MongoDb class and immediately check if it created. Then I just run some very simple function: `AddMessage`. This function defined as: ``` Future AddMessage(String message); ``` and return `completer.future`. If passed `message` is null then the function will fail completer as: ` .completeError('Message can not be null');` In actual test I want to test if `Future` completed successfully or with error. So above this is my try to understand how to test `Future` returns - the problems is this this test does not fail :( Could you write in answer a little code example how to test functions that return `Future` ? And in test I mean - sometimes I want to test return (on success) value and fail test if success value is incorrect and another test should fail then function will fail `Future` and enter to `onError:` block.

Original source

Related problems