5

it("should pass with..").. と it("should fail with..").. という 2 つのテスト ケースがあります。これをテストすると、2000 ミリ秒のタイムアウト エラーが発生しました。

describe("flickrphotoSearch", function () {
it("should pass with correct inputs", function (done) {
    flickrApplication.flickrPhotoSearch("hello", "flickr_user_Key", 1, handleData);
    function handleData(photoUrl, done) {
        this.setTimeout(1500);
        assert.isString(photoUrl.toString(), 'not a string');
        setTimeout(done, 1000);
    };
});
it("should fail with wrong key", function (callingDone) {
    flickrApplication.flickrPhotoSearch("hello", "wrong key", 1, handleData);
    function handleData(photoUrl, done) {
        this.setTimeout(1500);
        assert.equal(photoUrl.stat, "ok", photoUrl.message);
        setTimeout(done, 1000);
    };
});
});

最初のテストではタイムアウト超過エラーが発生しますが、2 番目のテストは正常に実行されています。どこが間違っているか教えてください。

4

1 に答える 1

1

これには 2 つの部分があります。まず、テストのタイムアウトを設定しようとするとsetTimeout、正しいオブジェクトでメソッドを呼び出していません。これは閉鎖によるものです:

describe("flickrphotoSearch", function () {
it("should pass with correct inputs", function (done) {
    # 'this' is the mocha test here.
    flickrApplication.flickrPhotoSearch("hello", "flickr_user_Key", 1, handleData);
    function handleData(photoUrl, done) {
        this.setTimeout(1500); # What's 'this' here? The global object.
        assert.isString(photoUrl.toString(), 'not a string');
        setTimeout(done, 1000);
    };
});

handleData呼び出されるとthis、関数はオブジェクト メソッドとしてではなく、それ自体で呼び出されるため、何にもバインドされません。クロージャーとthisバインディングの詳細については、この jQuery Learning Center の記事を参照してください。次のようにして修正できます。

flickrApplication.flickrPhotoSearch("hello", "flickr_user_Key", 1, handleData.bind(this));

ただし、この場合は、this.setTimeout(1500)handleData の外に移動しても同じ効果があります。

もう 1 つの部分は、2000 ミリ秒のタイムアウトを超えると、1500 ミリ秒の制限も超えてしまうということです。さらに、これは flickr API の応答時間に依存するため、非決定論的です。

私のアドバイスは、これが単体テストの場合 (統合テストとは対照的に)、flickr API をモック化することです。

于 2014-04-11T12:10:47.167 に答える