0

ノックアウト ビュー モデルの qunit ユニット テストを作成しようとしていますが、興味深い問題に遭遇しました。

私のビューモデルには、次の機能があります。

    Get = function (id) {
        return $.ajax({
            url: API + "/" + id,
            type: 'GET',
            dataType: 'json',
            timeout: Timeout,
            statusCode: {
                200: GetOneSuccess,
                404: ItemNotFound
            },
            error: function () {
                //Item(null);
            }
        });
    },

次に、単体テストで次のようにします。

vm.Get(vm.Item().Id()).then(function () {                    
   ok(false, "Failure!");
},function () {
   equal(vm.Item(), null, "Item was removed");
   start();
});

ItemNotFound は次のとおりです。

    ItemNotFound = function () {
        Item(null);
    }

API コントローラが "NotFound (Error 404)" を返した場合は、Item を null に設定します。「then」が呼び出されたときに ItemNotFound 関数がまだ完了していないため、テストが失敗したことがわかりました。

単体テストにタイムアウトを追加すると、次のように機能します。

            vm.Get(vm.Item().Id()).then(function () {                    
                    ok(false, "Failure!");
            },function () {
                    setTimeout(function () {
                        equal(vm.Item(), null, "Item was removed");
                        start();
                    }, 2000);
            });

誰にも考えはありますか?statusCodes を気にせず、エラー ハンドラですべてのエラー タイプを処理する必要がありますか? エレガントには見えません。

4

1 に答える 1

0

エラーハンドラーは、ステータスコード関数が実行される前に最初に実行されます。「then」関数は「成功コールバック」と「エラーコールバック」を取ります。したがって、本質的には、ステータスコード「notfound」が発生する前にエラー(失敗)が発生します。

タイムアウトを設定すると、関数はすぐに戻り、ステータスコードを起動し、設定されたタイムアウトに基づいて、その特定のコードを起動します。

それでもあなたが持っているコード構造が必要な場合は、これが私がそれを行う方法です。GET関数は、実際のajax呼び出しをカプセル化するDeffered promiseオブジェクトを返す必要があり、成功またはエラーハンドラーを指定せず、最初にstatusCodeから成功またはエラー関数を呼び出します。

私は同じためのフィドルを作成しました

http://jsfiddle.net/sujesharukil/BWA9D/15/

var data = {
    json: $.toJSON({
        text: 'some text',
        array: [1, 2, 'three'],
        object: {
            par1: 'another text',
            par2: [3, 2, 'one'],
            par3: {}
        }
    })
}


var callEcho = function(url) {
    return $.Deferred(function(def){
        $.ajax({
        url: url,
        type: "POST",
        data: data,
        statusCode: {
            200: function(data,xhr){
                GetOneSuccess();
                def.resolve(data);
            },
            404: function(xhr){
                ItemNotFound();
                def.reject();
            }
        }
    });    
}).promise();

};

function GetOneSuccess(){
    alert('Get One success Called');
}

function ItemNotFound(){
    alert('Item Not Found Called');
}

var testFunc = function(url){
    var js = callEcho(url);
    js.done(function(data){
        alert(JSON.stringify(data) + ' done function called');
    });

    js.fail(function(){
        alert('fail function called.');
    });
}

//fire the success
testFunc("/echo/json/" );

//fire the fail
testFunc("/echo/jso/");
于 2013-03-11T13:37:05.610 に答える