W jaki sposób można przetestować metodę, która zwraca Future
przed zakończeniem testu? Mam problem w miejscu, w którym mój tester jednostki kończy się przed zakończeniem metod asynchronicznych.Jak powinienem testować przyszłość w Dart?
Odpowiedz
Pełny przykład sposobu testowania z użyciem macierzy completion
jest następujący.
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})));
});
}
Uruchomiony test jednostki może nie zakończyć się przed ukończeniem tego kodu. Wydaje się więc, że test jednostkowy został wykonany poprawnie. Z Future
s ukończenie prawidłowego sposobu może zająć więcej czasu, ponieważ należy użyć wycinarki completion
dostępnej w pakiecie unittest.
Można by pokusić się na następujące rzeczy, które byłyby niewłaściwym sposobem testowania jednostki zwróconej Przyszłości w lotkę. OSTRZEŻENIE: poniżej jest nieprawidłowy sposób testowania kontraktów 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"]);
});
});
}
Inną możliwością jest użycie funkcji expectAsync1. analogowy roboczy do początkowego błędnego wariantu testu byłoby:
void main() {
test("testing a future",() {
Compute compute = new Compute();
compute.sumIt([1, 2, 3]).then(expectAsync1((Map m) {
Expect.equals(true, m.containsKey("value"));
Expect.equals(6, m["value"]);
}));
});
}
Zaletą w użyciu expectAsync1 do testowania asynchronicznym jest jego composability. Czasami testy naturalnie wymagają kilku kolejnych asynchronicznych bloków kodu. badanie próbki z mongo_db:
testCursorGetMore(){
var res;
Db db = new Db('${DefaultUri}mongo_dart-test');
DbCollection collection;
int count = 0;
Cursor cursor;
db.open().chain(expectAsync1((c){
collection = db.collection('new_big_collection2');
collection.remove();
return db.getLastError();
})).chain(expectAsync1((_){
cursor = new Cursor(db,collection,where.limit(10));
return cursor.each((v){
count++;
});
})).chain(expectAsync1((dummy){
expect(count,0);
List toInsert = new List();
for (int n=0;n < 1000; n++){
toInsert.add({"a":n});
}
collection.insertAll(toInsert);
return db.getLastError();
})).chain(expectAsync1((_){
cursor = new Cursor(db,collection,where.limit(10));
return cursor.each((v)=>count++);
})).then(expectAsync1((v){
expect(count,1000);
expect(cursor.cursorId,0);
expect(cursor.state,Cursor.CLOSED);
collection.remove();
db.close();
}));
}
Aktualizacja:
Zarówno Future i unittest API zostały zmienione, ponieważ pytanie było początkowo poprosił. Teraz jest możliwe, po prostu powrócić Future
z funkcji testu i unittest poprawnie wykonane z wszystkimi asynchroniczne funkcje chronione. W połączeniu z faktem, że chain
i then
metody Future
są teraz scalane, które zapewniają dobrą składnię do testów z kilkoma sekwencyjnymi blokami kodu. W obecnej wersji mongo_dart ten sam test wygląda następująco:
Future testCursorGetMore(){
var res;
Db db = new Db('${DefaultUri}mongo_dart-test');
DbCollection collection;
int count = 0;
Cursor cursor;
return db.open().then((c){
collection = db.collection('new_big_collection2');
collection.remove();
return db.getLastError();
}).then((_){
cursor = new Cursor(db,collection,where.limit(10));
return cursor.forEach((v){
count++;
});
}).then((dummy){
expect(count,0);
List toInsert = new List();
for (int n=0;n < 1000; n++){
toInsert.add({"a":n});
}
collection.insertAll(toInsert);
return db.getLastError();
}).then((_){
cursor = new Cursor(db,collection,null);
return cursor.forEach((v)=>count++);
}).then((v){
expect(count,1000);
expect(cursor.cursorId,0);
expect(cursor.state,State.CLOSED);
collection.remove();
return db.close();
});
}
ExpectAsync jest również przydatny, gdy trzeba przetestować nie samą przyszłość, ale niektóre zmiany właściwości obiektu – Martynas
Właśnie zwrócenie przyszłości działa również dla 'setUp()' i 'tearDown()', gdy muszą wykonać jakiś kod asynchroniczny, więc testy są nie wykonywane, dopóki nie zakończy się działanie 'setUp()'. –
Alternatywnie, oto, co robiłem. Jest to podobne do powyższych odpowiedzi:
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);
});
uzyskać odniesienie do przyszłości, i umieścić wszystkie moje oczekiwać oświadczenia wewnątrz zaproszenia then
. Następnie rejestruję numer expect(future, completes)
, aby się upewnić, że faktycznie się zakończył.
Podoba mi się również ten przykład. Widziałem w ten sposób łatwą drogę do przyszłości w łańcuchu. –
Zobacz rozdział dotyczący testów asynchronicznych w tym article lub dokumentację API dla expectAsync.
Poniżej znajduje się krótki przykład. Zauważ, że funkcja expectAsync() musi zostać wywołana, zanim zamknięcie zostanie przekazane do funkcji test().
import 'package:unittest/unittest.dart';
checkProgress() => print('Check progress called.');
main() {
test('Window timeout test',() {
var callback = expectAsync(checkProgress);
new Timer(new Duration(milliseconds:100), callback);
});
}
Innym sposobem czekać na przyszłość, aby zakończyć podczas testu jest przywrócenie go z zamknięciem przekazany do funkcji testowej.Zobacz ten przykład z artykułu związanego powyżej.
import 'dart:async';
import 'package:unittest/unittest.dart';
void main() {
test('test that time has passed',() {
var duration = const Duration(milliseconds: 200);
var time = new DateTime.now();
return new Future.delayed(duration).then((_) {
var delta = new DateTime.now().difference(time);
expect(delta, greaterThanOrEqualTo(duration));
});
});
}
Dla mockito
v 2+ Istnieje możliwość, aby to zrobić z pomocą
await untilCalled(mockObject.someMethod())
- 1. Dart, jak stworzyć przyszłość, aby powrócić we własnych funkcjach?
- 2. Ruby + Rspec: Jak powinienem testować attr_accessor?
- 3. Dartlang czekaj więcej niż jedną przyszłość
- 4. Konwersja Scala Przyszłość na Twitter Przyszłość
- 5. Jak przekształcić [Przyszłość [A], Przyszłość [B]] na przyszłość [Albo [A, B]]
- 6. Przyszłość dźwięku JavaScript?
- 7. Jak testować funkcje w Clojure?
- 8. Jak "testować" NoneType w python?
- 9. Jak testować w zakresie niszczenia
- 10. Jak testować puts w rspec
- 11. Jak utworzyć instancję niestandardowego elementu Dart Polymer w kodzie Dart?
- 12. Jak odblokować wyjątki w Dart?
- 13. Jak obsługiwać JSON w Dart
- 14. Jak stworzyć okienko w Dart?
- 15. Jak załadować obraz w Dart
- 16. Jak testować zapytania HQL?
- 17. Jak testować z MediatR
- 18. Jak testować Spring Integration
- 19. Przyszłość i stabilność IronPython
- 20. Jak testować bezpieczeństwo wątków
- 21. Jak testować wtyczki SBT
- 22. Jak testować Laravel Socialite
- 23. Jak testować makra Scala?
- 24. Jak nazywasz klasę Dart?
- 25. Przyszłość cmd & powershell
- 26. Przyszłość funkcji MySQL PHP
- 27. Jak profilować aplikację dart?
- 28. Przekształcanie słuchacza w przyszłość w java
- 29. Jak anulować kompletną przyszłość Java 8?
- 30. Jak uzyskać zgłoszenie wyjątku do zwiększenia :: przyszłość?
Wielkiej! Być może powinieneś przenieść nieprawidłowy kod z odpowiedzi na swoje pytanie. –
Co było w tym błędne? –
Ups, zrozumiałem, że pierwszy fragment kodu nie zadziałał ... Ale działa. Zapomnij o moim komentarzu, przepraszam. –