Saya suka mensimulasikan panggilan layanan web asinkron di aplikasi Dart saya untuk pengujian. Untuk mensimulasikan keacakan panggilan tiruan ini yang merespons (mungkin rusak), saya ingin memprogram pengolok saya untuk menunggu (tidur) selama jangka waktu tertentu sebelum mengembalikan 'Masa Depan'.
Bagaimana saya bisa melakukan ini?
unit-testing
mocking
dart
Vinnie
sumber
sumber
() => "1"
?await sleep1();
Edisi 2019:
Dalam Kode Async
await Future.delayed(Duration(seconds: 1));
Dalam Kode Sinkronisasi
import 'dart:io'; sleep(Duration(seconds:1));
Catatan: Ini memblokir seluruh proses (mengisolasi), sehingga fungsi asinkron lainnya tidak akan diproses. Ini juga tidak tersedia di web karena Javascript benar-benar hanya asinkron.
sumber
sleep()
benar-benar memblokir seluruh isolat. Tidak ada kode Dart yang akan berjalan sama sekali saat sedang tidur. Ini mungkin dikompilasi ke sesuatu seperti C ++std::this_thread::sleep_for
.Future.delayed()
menjadwalkan fungsi asinkron untuk dilanjutkan nanti, tetapi kemudian mengembalikan kontrol ke loop peristiwa Dart sehingga fungsi asinkron lainnya dapat terus berjalan.Tidak selalu itu yang Anda inginkan (terkadang Anda inginkan
Future.delayed
), tetapi jika Anda benar-benar ingin tidur di aplikasi baris perintah Dart, Anda dapat menggunakan dart: io'ssleep()
:import 'dart:io'; main() { sleep(const Duration(seconds:1)); }
sumber
await sleep()
dan mengharapkan pekerjaan lain berjalan selama tidur :(Saya menemukan bahwa ada beberapa implementasi di Dart untuk membuat eksekusi penundaan kode:
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."));
sumber
Untuk sintaks Dart 2+, dalam konteks fungsi asinkron:
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); }
sumber
Ini adalah tiruan berguna yang dapat menggunakan parameter opsional untuk membuat tiruan kesalahan:
Future _mockService([dynamic error]) { return new Future.delayed(const Duration(seconds: 2), () { if (error != null) { throw error; } }); }
Anda bisa menggunakannya seperti ini:
await _mockService(new Exception('network error'));
sumber
Saya juga perlu menunggu layanan selesai selama pengujian unit. Saya menerapkan cara ini:
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) { ... } ); } }
sumber