2012-12-03 26 views

答えて

12

completionマッチャーでテストする方法の完全な例は次のとおりです。

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}))); 
    }); 
} 

このコードが完了する前に、ユニットテストランナーが完了していない可能性があります。したがって、ユニットテストが正しく実行されたように見えます。 Futureでは、unittestパッケージで利用可能なcompletionマッチャーを利用するのに長時間かかる場合があります。

/** 
* 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)); 

一つは、ダーツで返された今後のテストユニットの間違った方法だろう次のことを行うように誘惑されるだろう。警告:以下は、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"]); 
    }); 
    }); 
} 
+0

グレートの助けを借りてそれを行うには可能性があります!おそらく、あなたの答えから間違ったコードをあなたの質問に移すべきでしょう。 –

+0

これについて間違っていたのは何ですか? –

+0

最初のコードスニペットは機能しませんでしたが、うまくいきました。私のコメントを忘れて、申し訳ありません。 –

14

expectAsync1関数を使用することもできます。テストの最初の間違ったバリアントの ワーキングアナログは次のようになります。非同期テストのためexpectAsync1を使用して

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"]); 
    })); 
    }); 
} 

一つの利点は、その構成可能性です。時には、テストでは必然的にいくつかのシーケンシャルな非同期コードブロックが必要になります。 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(); 
    })); 
} 

更新:質問が最初に頼まれたので、

将来とunittestモジュールのAPIの両方が変更されました。 テスト関数からFutureを返すことができ、unittestはすべての非同期ガード機能を適切に実行しました。 chainthenの方法がFutureであることを組み合わせて、いくつかのシーケンシャルコードブ​​ロックでテストするための素晴らしい構文を提供するようになりました。 mongo_dartの現在のバージョンでは、同じテストは次のようになります。

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(); 
    }); 
} 
+0

ExpectAsyncは未来そのものではなくオブジェクトプロパティの変更をテストする必要があるときに便利です – Martynas

+0

未来を返すだけで、いくつかの非同期コードを実行する必要があるときに 'setUp()'と 'tearDown() 'setUp()'が終了するまで実行されません。 –

10

これとは別の方法として、私がやってきたことをここに示します。これは、上記の回答に似ています:

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); 
}); 

私は未来への参照を取得し、すべての私はthenコール内のステートメントを期待して置きます。その後、実際に完了するためにexpect(future, completes)を登録します。

+0

私はこの例も好きです。私はこのような方法でチェーンの先物を手に入れる簡単な方法を知ることができました。 –

2

articleの非同期テストに関するセクションまたはexpectAsyncのAPIドキュメントを参照してください。

以下は簡単な例です。 expectAsync()は、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); 
    }); 
} 

テスト中に完了するために、将来を待つもう一つの方法は、テスト関数に渡されたクロージャからそれを返すことです。上記リンク先の記事からこの例を参照してください:。

mockito Vが
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)); 
    }); 
    }); 
} 
1

2+

await untilCalled(mockObject.someMethod()) 
関連する問題