2013-10-16 56 views
0

我目前正在研究一個移動應用程序,我決定使用JQuery Mobile來實現它。然而,由於它是一個官方應用程序,它需要我對它進行測試,並且我決定和我一起學習在學校處理的茉莉花。使用Jasmine,JQuery Mobile和異步AJAX請求的組合測試DOM

目前我有一個客戶端和服務器端使用AJAX($.getJSON)請求進行通信。

當其中一個AJAX請求轉發到它的callback方法時,它將調用Notification類來實現帶有通知的div

我當時的問題是,它似乎總是當我使用下面的代碼工作:

window.setTimeout(function() { 
    var expectedResult = "error"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}, 4000); 

然而,幾天後,我開始了新的模塊,並編輯這些值它繼續工作,因爲它的舊 - 非現有的代碼,這將是非常錯誤的。

所以我注意到這個單元測試從來沒有真正的工作。

所以我開始尋找替代方法,發現runswaitsFor函數,但我似乎無法讓它們工作。

所以這裏是一個考驗:

it('should display an error when trying to add a new contact', function() { 
    runs(function() { 
     var contact = new Contact(); 
     contact.addContact(); 
    }); 

    waitsFor(function() { 
     expect($("#test .ui-content .contentContainer .notification")).toBeVisible(); 
    }, 5000); 

    var expectedResult = "asdf"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}); 

回調方法:

this.addContact_callback = function (data) { 
    $('#createContactForm')[0].reset(); 
    $('.ui-dialog').dialog('close'); 
    window.setTimeout(function() { 
     (new Contact()).retrieveContactList(); 
     (new NotificationBox()).show(data.message[0], data.message[1]); 
    }, 250) 
}; 

我的通知:

function NotificationBox() { 
    this.show = function (message, type) { 
     var activePage = $("body .ui-page-active").attr("id"); 
     var create = "<div class='notification " + type + "'>" + message + "</div>"; 
     $("#" + activePage + " .ui-content .contentContainer .notification").remove(); 
     $("#" + activePage + " .ui-content .contentContainer").prepend(
      $(create).hide().fadeIn('slow').delay(2500).fadeOut('slow', function() { 
       $(this).remove(); 
      }) 
     ); 
    }; 
} 

我希望有人能夠給我提供一個解決方案這個主要問題。

此致 Larssy1

回答

1

您濫用waitsFor方法。如果您閱讀official documentationwaitsFor需要返回一個指示等待時間是否結束的值。

什麼你可能想要做的是以下幾點:

waitsFor(function() { 
    return $("#test .ui-content .contentContainer .notification").is(":visible"); 
}, 5000); 

您還缺少測試的最後部分運行塊。

runs(function() { 
    var expectedResult = "asdf"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}); 
+0

這兩種方法都在那裏,檢查第二個代碼片段。由於我沒有答案,我目前正在重構我的代碼,它允許我不通過DOM檢查,而是通過返回的值。 – larssy1

0

雖然它可能不被視爲解決方案,但它確實創建了更好的可管理和可測試的代碼。

在我給出的代碼示例中,我將代碼轉發到外部回調方法,如我在使用addContact_callback時給出的代碼。跟蹤實際結果的唯一方法是確定notification元素類的文本。

說完這句話,很明顯,如果你面對這個問題,你可能已經寫了髒代碼。

因此,我將我的代碼更改爲更好的東西,它使用內部回調方法。這意味着代碼看起來像這樣的事情:

function handleSomething() { 
    this.retrieveSomething(function (data) { 
     console.log(data); 
    }); 
} 

function retrieveSomething (callback) { 
    $.ajax({ 
     type: "GET", 
     url: "127.0.0.1/my.php", 
     success: function (data, status, xhr) { 
      return callback($.parseJSON(data); 
     } 
    }); 
} 

這可以確保我的代碼是比較容易的方式來測試,因爲我可以實現自定義的回調函數的單元測試。

還記得舊的單元測試?嗯,這又來自:

window.setTimeout(function() { 
    var expectedResult = "error"; 
    var result = $("#test .ui-content .contentContainer .notification").text(); 
    expect(result).toEqual(expectedResult); 
}, 4000); 

到:

var contact = new Contact(); 
contact.retrieveSomething(function (data) { 
    var expectedResult = (new Contact()).errorMessages[4]; 
    expect(data.message).toBe(expectedResult); 
}); 

Conslusion:確保你隨時可以測試你的回報輸出,而不是簡單地將其移動到用戶界面,然後試圖測試的結果是否和你所期望的一樣。