2014-06-05 15 views
5

Tôi rất mới để kiểm tra đơn vị, mocha và should.js, và tôi đang cố gắng viết một thử nghiệm cho một phương thức không đồng bộ trả về lời hứa. Đây là mã thử nghiệm của tôi:should.js không gây ra kiểm tra mocha thất bại

var should = require("should"), 
    tideRetriever = require("../tide-retriever"), 
    moment = require("moment"), 
    timeFormat = "YYYY-MM-DD-HH:mm:ss", 
    from = moment("2013-03-06T00:00:00", timeFormat), 
    to = moment("2013-03-12T23:59:00", timeFormat), 
    expectedCount = 300; 

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function() { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
      }, 
      function(err) { // reject 
       should.fail("Promise rejected", err); 
      } 
     ); 
    }); 
}); 

Khi tôi tự kiểm tra phương pháp tideRetriever.get, nó liên tục giải quyết một loạt các yếu tố 27 (như mong đợi), nhưng các thử nghiệm sẽ không thất bại không phụ thuộc vào giá trị của expectedCount. Đây là bài kiểm tra thủ công đơn giản của tôi:

tideRetriever.get(from, to).then(
    function(entries) { 
     console.log(entries, entries.length); 
    }, 
    function(err) { 
     console.log("Promise rejected", err); 
    } 
); 

Tôi cũng có thể đăng nguồn cho mô-đun đang được kiểm tra nếu cần.

Tôi có hiểu nhầm về Mocha hoặc should.js không? Mọi sự trợ giúp sẽ rất được trân trọng.

Trả lời

7

CẬP NHẬT

Tại một số điểm Mocha bắt đầu để hỗ trợ trở Promise từ thử nghiệm thay vì thêm done() callbacks. Câu trả lời gốc vẫn hoạt động, nhưng thử nghiệm có vẻ sạch hơn với cách tiếp cận này:

it("should retrieve and parse tide CSV data", function() { 
    return tideRetriever.get(from, to).then(
     function(entries) { 
      entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
     } 
    ); 
}); 

Hãy kiểm tra this gist để có ví dụ hoàn chỉnh.

ORIGINAL

THẬN TRỌNG. Câu trả lời được chấp nhận chỉ hoạt động với mã không đồng bộ bình thường, không phải với Lời hứa (tác giả sử dụng).

Sự khác biệt là ngoại lệ được ném từ lời gọi lại lời hứa không thể bị bắt bởi ứng dụng (trong trường hợp của chúng tôi Mocha) và do đó kiểm tra sẽ không thành công theo thời gian chờ và không phải do xác nhận thực tế. Xác nhận có thể được ghi lại hoặc không phụ thuộc vào triển khai Promise. Xem thêm thông tin về điều này tại when documentation.

Để xử lý đúng cách này với Lời hứa, bạn nên chuyển đối tượng err đến cuộc gọi lại done() thay vì ném nó. Bạn có thể làm điều đó bằng cách sử dụng phương pháp Promise.catch() (không phải trong số onRejection() gọi lại số Promise.then(), bởi vì nó không bắt ngoại lệ từ onFulfilment() gọi lại cùng một phương thức).Xem ví dụ dưới đây:

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function(done) { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
       done(); // test passes 
      }, 
      function(err) { // reject 
       done(err); // Promise rejected 
      } 
     ).catch(function (err) { 
      done(err); // should throwed assertion 
     }); 
    }); 
}); 

PSdone() callback được sử dụng trong ba nơi để trang trải tất cả các trường hợp có thể. Tuy nhiên onRejection() gọi lại có thể được xóa hoàn toàn nếu bạn không cần bất kỳ logic đặc biệt nào bên trong nó. Promise.catch() cũng sẽ xử lý các từ chối trong trường hợp này.

+0

Bạn quên thêm "thực hiện" làm tham số của hàm – Chaoste

+0

@Chaoste cảm ơn, đã sửa. –

4

Khi kiểm tra mã không đồng bộ, bạn cần phải thông báo cho Mocha khi quá trình kiểm tra hoàn tất (bất kể nó đã qua hay thất bại). Điều này được thực hiện bằng cách xác định một đối số cho hàm kiểm tra, mà Mocha điền với hàm done. Vì vậy, mã của bạn có thể trông như thế này:

describe("tide retriever", function() { 
    it("should retrieve and parse tide CSV data", function(done) { 
     tideRetriever.get(from, to).then(
      function(entries) { // resolve 
       entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount); 
       done(); 
      }, 
      function(err) { // reject 
       should.fail("Promise rejected", err); 
       done(); 
      } 
     ); 
    }); 
}); 

Lưu ý rằng cách thức Mocha biết đây là một thử nghiệm async và nó cần phải đợi cho đến khi done() được gọi là chỉ bằng cách xác định lập luận đó.

Ngoài ra, nếu lời hứa của bạn có trình xử lý "hoàn tất", cả hai đều có thể thành công và thất bại, bạn có thể gọi số done() trong đó, do đó, hãy lưu cuộc gọi. Thông tin

thêm tại: http://mochajs.github.io/mocha/#asynchronous-code

+0

Cảm ơn bạn. Tôi nghĩ rằng 'done' chức năng chỉ để xác định có nên chạy thử nghiệm đồng bộ với các xét nghiệm khác. – SimpleJ

+0

Tôi sẽ tăng gấp đôi upvote này nếu tôi có thể. Tầm quan trọng của việc truyền 'done' arg đến test (hàm gọi lại của' nó' rất dễ bỏ qua, nhưng nguồn gốc của rất nhiều nhầm lẫn! – Ben

Các vấn đề liên quan