2011-07-16 69 views
6

我有一個使用jQuery構建的動態頁面。 HTML片段從mustache模板加載。這些模板是從網址下載,我想單元測試整體的HTML結構:如何使用JsTestDriver測試jquery和ajax調用?

的JsTestDriver測試:

AppTest = TestCase("AppTest") 

AppTest.prototype.test = function() { 
    var actualHtml = ""; 

    getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
     actualHtml = html; 
    }); 

    assertEquals("expected html", actualHtml); 
}; 

,代碼:

function getHtml(json, resultFunc) { 
    jQuery.ajax({ 
      url: "url/to/mustache/template", 
      success: function(view) { 
        resultFunc(mergeArticleModelAndView(json, view)); 
      }, 
      error: function(jqXHR, textStatus, errorThrown) { 
        resultFunc(textStatus + " errorThrown: " + errorThrown); 
      }, 
      dataType: 'text', 
      async: false 
    }); 
} 

然後我啓動測試和結果是:

$ java -jar JsTestDriver-1.3.2.jar --port 9876 --browser /usr/bin/firefox --tests all 
F 
Total 1 tests (Passed: 0; Fails: 1; Errors: 0) (8,00 ms) 
    Firefox 5.0 Linux: Run 1 tests (Passed: 0; Fails: 1; Errors 0) (8,00 ms) 
    AppTest.test failed (8,00 ms): AssertError: expected "expected html" but was "error errorThrown: [Exception... \"Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)\" nsresult: \"0x80004005 (NS_ERROR_FAILURE)\" location: \"JS frame :: http://localhost:9876/test/main/js/jquery.min.js :: <TOP_LEVEL> :: line 16\" data: no]" 
()@http://localhost:9876/test/test/js/app_test.js:25 

所以錯誤回調已被調用,a第二,我不明白爲什麼它JsTestDriver打破,並用瀏覽器

最後一件事,在jsTestDriver.conf手動調用應用程序時的代碼工作:

server: http://localhost:9876 

load: 
    - test/js/app_test.js 
    - main/js/jquery.min.js 
    - main/js/jquery.mustache.js 
    - main/js/app.js 

謝謝您的建議。更一般地說,你使用什麼單元測試框架進行JavaScript和使用DOM和jQuery的命令行測試?

+0

我用[茉莉](https://github.com/pivotal/jasmine)。我不會通過命令行執行它們,但有一些插件可以做到這一點。我喜歡茉莉花,它是否生成類似散文的測試代碼。你可以嵌套你的測試。還有一個jQuery的插件,但沒有它我很好。 –

回答

3

是的,它是可以做到相當與jQuery相同:

測試代碼(只是設置的測試是一樣的):

TestCase("AppTest", { 
    setUp: function() { 
     this.xhr = Object.create(fakeXMLHttpRequest); 
     this.xhr.send=function() { 
      this.readyState = 4; 
     }; 
     this.xhr.getAllResponseHeaders=stubFn({}); 
     this.xhr.responseText="<expected data>"; 
     jQuery.ajaxSettings.isLocal=stubFn(true); 
     jQuery.ajaxSettings.xhr=stubFn(this.xhr); 
    }, 
// same test method 

而且產品代碼:

function getHtml(model, resultFunc) { 
     $.get("/url/to/template", function(view) { 
       resultFunc(mergeArticleModelAndView(model, view)); 
     }); 
} 

這就是我們選擇的解決方案。

4

我找到了一個方法來做到這一點:就是模擬ajax調用。在http://tddjs.com/有在第12章這樣做的例子,Git倉庫,在這裏:http://tddjs.com/code/12-abstracting-browser-differences-ajax.git

所以測試代碼:

TestCase("AppTest", { 
    setUp: function() { 
     tddjs.isLocal = stubFn(true); 
     var ajax = tddjs.ajax; 
     this.xhr = Object.create(fakeXMLHttpRequest); 
     this.xhr.send=function() { 
      this.readyState = 4; 
      this.onreadystatechange(); 
     }; 
     this.xhr.responseText="<expected data>"; 
     ajax.create = stubFn(this.xhr); 
    }, 


    "test article html ok": function() { 
     var actualHtml = ""; 

     getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
      actualHtml = html; 
     }); 

     assertEquals("<expected html>", actualHtml); 
    } 
}); 

而且產品代碼:

function getHtml(model, resultFunc) { 
     tddjs.ajax.get("http://url/to/template", { 
       success: function (xhr) { 
         resultFunc(mergeArticleModelAndView(model, xhr.responseText)); 
       } 
     }); 
} 

閱讀完jQuery代碼後,我認爲可以嘲笑jQuery ajax請求。比照還jquery 1.5 mock ajax

5

另一種方法是讓JsTestDriver爲您的模板和一些測試JSON數據提供服務。以下配置允許您將靜態JSON測試數據(例如my_data.json)放入src/test/webapp/json和src/main/webapp/templates中的Mustache模板中。如果你的口味太過Maven-y,你可以改變它來匹配你的源代碼佈局。請注意,JsTestDriver服務的資源是/ test/pre-pended到serve屬性中指定的URI,因此src/test/webapp/json/my_data.json實際上是從http:// localhost:9876 /測試/ SRC /測試/ web應用/ JSON/my_data.json。

server: http://localhost:9876 

serve: 
- src/main/webapp/templates/*.html 
- src/test/webapp/json/*.json 

load: 
- src/main/webapp/js/*.js 
- src/main/webapp/js/libs/*.js 

test: 
- src/test/webapp/js/*.js 

然後,在測試案例中,您可以輕鬆加載模板和JSON數據。

testLoadTemplateAndData : function() { 

     // Variables 
     var onComplete, template, data, expected, actual, templateLoaded, dataLoaded; 
     dataLoaded = false; 
     templateLoaded = false; 
     expected = "<h2>Your expected markup</h2>"; 

     // Completion action 
     onComplete = function() { 
      if (dataLoaded && templateLoaded) { 

       // Render the template and data 
       actual = Mustache.to_html(template, data); 

       // Compare with expected 
       assertEquals('Markup should match', expected, actual); 

      } 
     }; 

     // Load data with jQuery 
     $.ajax({ 
      url : '/test/src/test/webapp/json/demo.json', 
      success : 
       function (result) { 
        data = result; 
        dataLoaded = true; 
      }, 
      error : 
       function() { 
        fail("Data did not load."); 
      }, 
      complete : 
       function() { 
        onComplete(); 
       } 
      } 
     ); 

     // Load the template with jQuery 
     $.get('/test/src/main/webapp/templates/demo.html', 
      function(result) { 
       template = result; 
       templateLoaded = true; 
      } 
     ) 
     .error(function() { fail("Template did not load."); }) 
     .complete(function() { 
      onComplete(); 
     }); 

    } 

當兩個jQuery回調都完成時,Mustache應該使用JSON數據解析模板並呈現預期的輸出。

0

隨着sinon.js那麼就更簡單了:

TestCase("AppTest", { 
setUp: function() { 
    this.server = sinon.fakeServer.create(); 
}, 
tearDown: function() { 
    this.server.restore(); 
}, 

"test article html ok": function() { 
    this.server.respondWith("mustache template"); 
    this.server.respond(); 
    var actualHtml = ""; 

    getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
     actualHtml = html; 
    }); 

    assertEquals("<expected html>", actualHtml); 
}