2013-02-14 42 views
10

Sử dụng Mocha, tôi đang cố kiểm tra xem một nhà xây dựng có phát sinh lỗi hay không. Tôi không thể thực hiện điều này bằng cách sử dụng cú pháp mong đợi, vì vậy tôi muốn làm như sau:Kiểm tra lỗi dự kiến ​​trong Mocha

it('should throw exception when instantiated', function() { 
    try { 
    new ErrorThrowingObject(); 
    // Force the test to fail since error wasn't thrown 
    } 
    catch (error) { 
    // Constructor threw Error, so test succeeded. 
    } 
} 

Điều này có thể?

+0

"lực lượng mocha thử nghiệm để thất bại "âm thanh như bạn muốn' mong đợi (false) .to.be.true', nhưng những gì thực sự được thảo luận là thử nghiệm thất bại dự kiến, tôi đã yêu cầu chỉnh sửa tiêu đề cho phù hợp. – OJFord

Trả lời

7

Bạn có thể thử sử dụng cấu trúc Chai'sthrow. Ví dụ:

expect(Constructor).to.throw(Error); 
+1

lý do tại sao bạn không thể chỉ trả về false; để làm một bài kiểm tra mocha thất bại? – PositiveGuy

+0

với thực hiện() bạn vượt qua một trường hợp lỗi như vậy: done (new Error()), mà không có "done()" gọi lại, bạn chỉ cần ném một lỗi, thay vì trả về một lỗi –

1

Nếu bạn đang sử dụng should.js bạn có thể làm (new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')

Nếu bạn không muốn nên một thư viện riêng biệt, bạn cũng có thể làm điều gì đó như thế này:

it('should do whatever', function(done) { 
    try { 
     ... 
    } catch(error) { 
     done(); 
    } 
} 

Bằng cách này, bạn biết lỗi bị bắt nếu thử nghiệm kết thúc. Nếu không, bạn sẽ nhận được một lỗi thời gian chờ.

+0

(new ErrorThrowingObject).throw ('Option Error Text hoặc Regular Expression here') không hoạt động, cần phải được bọc trong một hàm ẩn danh như sau: (function() {new ErrorThrowingObject}). should.throw ('Tùy chọn Lỗi Văn bản hoặc Cụm từ Thông dụng ở đây ') –

+0

hoặc bạn chỉ có thể làm điều này ErrorThrowingObject.should.throw (' Tùy chọn Lỗi Văn bản hoặc Biểu thức Chính quy tại đây ') –

25

should.js

Sử dụng should.js thư viện với should.fail

var should = require('should') 
it('should fail', function(done) { 
    try { 
     new ErrorThrowingObject(); 
     // Force the test to fail since error wasn't thrown 
     should.fail('no error was thrown when it should have been') 
    } 
    catch (error) { 
    // Constructor threw Error, so test succeeded. 
    done(); 
    } 
}); 

Alternative bạn có thể sử dụng nên throwError

(function(){ 
    throw new Error('failed to baz'); 
}).should.throwError(/^fail.*/) 

Chai

Và với chai sử dụng t ông throw api

var expect = require('chai').expect 
it('should fail', function(done) { 
    function throwsWithNoArgs() { 
    var args {} // optional arguments here 
    new ErrorThrowingObject(args) 
    } 
    expect(throwsWithNoArgs).to.throw 
    done() 
}); 
+0

Điều gì sẽ xảy ra nếu throwsWithNoArgs không trả lại lỗi mà chỉ khi nhận được thông số sai? và tôi muốn thử nghiệm với các thông số khác nhau? như: ** expect (throwsWithNoArguments.call (null, x1, x2)). to.throw (Error) ** sẽ là một tùy chọn? – alexserver

+1

Kỳ vọng (ném) luôn gọi hàm 'throws' không có đối số. Trong trường hợp của bạn, bạn có thể thay đổi cơ thể throwsWithNoArgs để gọi một hàm khác với các paramemers không chính xác. Hoặc bạn có thể sử dụng bind 'expect (throwsWithIncorrectArgs.bind (null, x1, x2)). To.throw (Error)' – Noah

9

Chai bây giờ có

should.fail()expect.fail()

https://github.com/chaijs/chai/releases/tag/2.1.0

+1

Đó là 'expect.fail()', NOT 'expect.to.fail()'. Tôi sẽ chỉnh sửa .. –

+0

um ... hoặc là tôi nghĩ? ... bạn có thể dính vào "để" vào chuỗi nếu bạn muốn, và ngữ pháp của nó theo cách đó, đó là lý do tại sao các từ nhỏ được cung cấp ("Sau đây được cung cấp như getters chuỗi để cải thiện khả năng đọc của các xác nhận của bạn. không cung cấp khả năng kiểm tra trừ khi chúng bị ghi đè bởi plugin. ") – shaunc

+0

' expect.fail' là phương thức tĩnh duy nhất của 'mong đợi' như bạn có thể thấy [ở đây] (https://github.com/chaijs/chai /blob/master/lib/chai/interface/expect.js). Không có xâu xích tĩnh..'expect.to' không tồn tại (nhưng 'mong đợi (...). To' tồn tại) –

3

2017 câu trả lời khi bạn cần phải làm điều này với mã async: sử dụng chờ đợi và không cần bất kỳ các thư viện khác.

it('Returns a correct error response making a broken order', async function(){ 
    this.timeout(5 * 1000); 
    var badOrder = {} 
    try { 
    var result = await foo.newOrder(badOrder) 
    // The line will only be hit if no error is thrown above! 
    throw new Error(`Expected an error and didn't get one!`) 
    } catch(err) { 
    var expected = `Missing required field` 
    assert.equal(err.message, expected) 
    } 
}); 

Lưu ý rằng người đăng chỉ đang thực hiện mã đồng bộ, nhưng tôi mong đợi nhiều người sử dụng async được dẫn đầu ở đây theo tiêu đề câu hỏi!

+0

Điều này không có ý nghĩa với tôi. Các câu hỏi đặt ra là hỏi về một hàm tạo, sẽ luôn luôn đồng bộ, do đó không cần phải có sự đồng bộ/chờ đợi. Tiếp theo, không cần phải ném một lỗi trong 'try', chỉ cần đặt mã khẳng định trong' final'. –

+0

@CodeBling Chắc chắn đã đồng ý, người hỏi câu hỏi đã hỏi về một số mã đồng bộ, nhưng tiêu đề 'kiểm tra thất bại dự kiến ​​trong mocha' đã dẫn đến một nhóm người ở đây cần kiểm tra phần lớn mã JS, tức là không đồng bộ, do đó upvotes. – mikemaccana

+0

Đó là công bằng, có lẽ một downvote là một chút khắc nghiệt. Vẫn nghĩ rằng câu trả lời sẽ hữu ích hơn nếu nó làm rõ rằng 'await' sẽ chỉ giúp cho các bài kiểm tra không đồng bộ. Bỏ phiếu bị khóa cho đến khi câu trả lời được chỉnh sửa nhưng tôi sẵn sàng thay đổi nó –

2

Mặc định Mocha đang sử dụng Khẳng định từ node.js (https://nodejs.org/api/assert.html). Bạn không cần bất kỳ thư viện bên ngoài nào để kiểm tra xem một phương thức có phát sinh lỗi hay không.

Khẳng định có một phương pháp - assert.throws, nó có ba thông số, nhưng chỉ có hai vấn đề thực sự ở đây:

  • chức năng - đây vượt qua chức năng, không hoạt động gọi
  • lỗi - đây vượt qua hoặc constructor đối tượng hoặc chức năng để kiểm tra lỗi

Hãy tưởng tượng rằng bạn có một hàm gọi là sendMessage(message) sẽ phát sinh lỗi khi thông số thư không được đặt. Mã hàm:

function sendMessage(message) { 
    if (!message || typeof message !== 'string') { 
    throw new Error('Wrong message'); 
    } 
    // rest of function 
} 

Ok, vì vậy để kiểm tra, bạn cần thêm chức năng để bao gồm đầu vào. Tại sao? Vì assert.throws không cung cấp bất kỳ cơ hội nào để truyền tham số cho hàm sẽ được kiểm tra.

Vì vậy, thay vì

// WRONG 
assert.throws(sendMessage, Error); // THIS IS WRONG! NO POSSIBILITY TO PASS ANYTHING 

bạn cần để tạo ra chức năng ẩn danh:

// CORRECT 
assert.throws(() => { 
    sendMessage(12); // usage of wanted function with test parameters 
}, Error) 

Bạn có thể thấy sự khác biệt? Thay vì truyền hàm trực tiếp, tôi đã đặt hàm gọi bên trong hàm ẩn danh, với mục đích gọi nó bằng đầu vào được chuẩn bị.

Còn về tham số thứ hai. Nó phụ thuộc vào loại lỗi nên được ném, trong ví dụ trên Error đối tượng đã được ném, vì vậy tôi đã phải đặt có Error. Kết quả của hành động này, assert.throws so sánh nếu đối tượng được ném là đối tượng cùng loại. Nếu thay vì Error thứ gì đó khác sẽ được ném, thì phần này cần được thay đổi. Ví dụ: thay vì Error Tôi sẽ ném một giá trị loại String.

function sendMessage(message) { 
    if (!message || typeof message !== 'string') { 
    throw 'Wrong message'; // change to String 
    } 
    // rest of function 
} 

Bây giờ cuộc gọi thử nghiệm

assert.throws(() => { 
    sendMessage(12); // usage of wanted function with test parameters 
}, (err) => err === 'Wrong message') 

Thay vì Error trong tham số thứ hai tôi đã sử dụng chức năng so sánh để so sánh lỗi ném với sự mong đợi.

0

Với Chaithrow (ES2016)

http://chaijs.com/api/bdd/#method_throw

Để rõ ràng ... này hoạt động

it('Should fail if ...', done => { 
    let ret =() => { 
     MyModule.myFunction(myArg); 
    }; 
    expect(ret).to.throw(); 
    done(); 
}); 

này không hoạt động

it('Should fail if ...', done => { 
    let ret = MyModule.myFunction(myArg); 
    expect(ret).to.throw(); 
    done(); 
}); 
Các vấn đề liên quan