I like to simulate an asynchronous web service call in my Dart application for testing. To simulate the randomness of these mock calls responding (possibly out of order) I\
I found that there are several implementations in Dart to make the code delay execution:
new Future.delayed(const Duration(seconds: 1)); //recommend
new Timer(const Duration(seconds: 1), ()=>print("1 second later."));
sleep(const Duration(seconds: 1)); //import 'dart:io';
new Stream.periodic(const Duration(seconds: 1), (_) => print("1 second later.")).first.then((_)=>print("Also 1 second later."));
//new Stream.periodic(const Duration(seconds: 1)).first.then((_)=>print("Also 1 second later."));
This a useful mock that can take an optional parameter to mock an error:
Future _mockService([dynamic error]) {
return new Future.delayed(const Duration(seconds: 2), () {
if (error != null) {
throw error;
}
});
}
You can use it like this:
await _mockService(new Exception('network error'));
For Dart 2+ syntax , in a async function context:
import 'package:meta/meta.dart'; //for @required annotation
void main() async {
void justWait({@required int numberOfSeconds}) async {
await Future.delayed(Duration(seconds: numberOfSeconds));
}
await justWait(numberOfSeconds: 5);
}
You can also use the Future.delayed factory to complete a future after a delay. Here is an example of two functions that return a string asynchronously after a delay:
import 'dart:async';
Future sleep1() {
return new Future.delayed(const Duration(seconds: 1), () => "1");
}
Future sleep2() {
return new Future.delayed(const Duration(seconds: 2), () => "2");
}
I also needed to wait for a service to complete during a unit test. I implemented this way:
void main()
{
test('Send packages using isolate', () async {
await SendingService().execute();
});
// Loop to the amount of time the service will take to complete
for( int seconds = 0; seconds < 10; seconds++ ) {
test('Waiting 1 second...', () {
sleep(const Duration(seconds:1));
} );
}
}
...
class SendingService {
Isolate _isolate;
Future execute() async {
...
final MyMessage msg = new MyMessage(...);
...
Isolate.spawn(_send, msg)
.then<Null>((Isolate isolate) => _isolate = isolate);
}
static void _send(MyMessage msg) {
final IMyApi api = new IMyApi();
api.send(msg.data)
.then((ignored) {
...
})
.catchError((e) {
...
} );
}
}
It's not always what you want (sometimes you want Future.delayed
), but if you really want to sleep in your Dart command-line app, you can use dart:io's sleep()
:
import 'dart:io';
main() {
sleep(const Duration(seconds:1));
}