使用Mocha,我试图测试构造函数是否抛出错误。我无法使用expect语法执行此操作,因此我想执行以下操作:
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.
}
}
这可能吗?
答案 0 :(得分:30)
将should.js库与 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();
}
});
替代方案,您可以使用“throwError
”(function(){
throw new Error('failed to baz');
}).should.throwError(/^fail.*/)
使用throw api
的chaivar expect = require('chai').expect
it('should fail', function(done) {
function throwsWithNoArgs() {
var args {} // optional arguments here
new ErrorThrowingObject(args)
}
expect(throwsWithNoArgs).to.throw
done()
});
答案 1 :(得分:11)
您可以尝试使用Chai's throw
构造。例如:
expect(Constructor).to.throw(Error);
答案 2 :(得分:11)
should.fail()
和expect.fail()
答案 3 :(得分:9)
2017如果您需要使用异步代码执行此操作:使用await和不需要任何其他库。
it('Returns a correct error response when 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)
}
});
请注意,海报只是在进行同步代码,但我希望很多使用async的人都会被问题标题带到这里!
答案 4 :(得分:5)
默认情况下,Mocha使用node.js(https://nodejs.org/api/assert.html)中的断言。您不需要任何外部库来检查方法是否抛出错误。
Assert有一个方法 - assert.throws
,它有三个参数,但这里只有两个真正重要:
让我们假设您有一个名为sendMessage(message)
的函数,它在未设置message参数时抛出错误。功能代码:
function sendMessage(message) {
if (!message || typeof message !== 'string') {
throw new Error('Wrong message');
}
// rest of function
}
好的,所以为了测试它,你需要额外的功能来覆盖输入。为什么?因为assert.throws
没有任何机会将参数传递给将要测试的函数。
所以而不是
// WRONG
assert.throws(sendMessage, Error); // THIS IS WRONG! NO POSSIBILITY TO PASS ANYTHING
您需要创建匿名函数:
// CORRECT
assert.throws(() => {
sendMessage(12); // usage of wanted function with test parameters
}, Error)
你能看出区别吗?我没有直接传递函数,而是将函数调用放在匿名函数中,目的是用准备好的输入调用它。
第二个参数怎么样?这取决于应该抛出什么样的错误,在上面的示例Error
抛出了对象,所以我不得不放在那里Error
。在此操作的结果中,assert.throws
比较抛出的对象是否是相同类型的对象。如果不是Error
会抛出不同的东西,那么这个部分需要改变。例如,我将抛出Error
类型的值而不是String
。
function sendMessage(message) {
if (!message || typeof message !== 'string') {
throw 'Wrong message'; // change to String
}
// rest of function
}
现在进行测试呼叫
assert.throws(() => {
sendMessage(12); // usage of wanted function with test parameters
}, (err) => err === 'Wrong message')
而不是第二个参数中的Error
我使用了比较函数来比较抛出的错误和期望值。
答案 5 :(得分:3)
MarkJ接受的答案是比其他人更方便的方式。 让我在现实世界中展示一些例子:
function fn(arg) {
if (typeof arg !== 'string')
throw TypeError('Must be an string')
return { arg: arg }
}
describe('#fn', function () {
it('empty arg throw error', function () {
expect(function () {
new fn()
}).to.throw(TypeError)
})
it('non-string arg throw error', function () {
expect(function () {
new fn(2)
}).to.throw(TypeError)
})
it('string arg return instance { arg: <arg> }', function () {
expect(new fn('str').arg).to.be.equal('str')
})
})
答案 6 :(得分:1)
如果您使用的是should.js,则可以执行(new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')
如果你不想要一个单独的库,你也可以这样做:
it('should do whatever', function(done) {
try {
...
} catch(error) {
done();
}
}
这样,您就知道测试完成后会捕获错误。否则,您将收到超时错误。
答案 7 :(得分:1)
如果您不想将大量源包装到expect
参数中,或者如果要传递的参数太多而又变得很丑陋,则仍然可以使用原始语法来完成此操作通过利用提供的done
参数(但最初被忽略):
it('should throw exception when instantiated', function(done: Done) {
try {
new ErrorThrowingObject();
done(new Error(`Force the test to fail since error wasn't thrown`));
}
catch (error) {
// Constructor threw Error, so test succeeded.
done();
}
}
由于您在此处使用done
,因此可以在try
中执行位于其上方的任意代码,然后精确指定要在源中记录故障的位置。
通常情况下,某人可能会倾向于使用throw
或assert(false)
,但是它们都会被catch
的{{1}}捕获,并导致您进行一些元操作-检查以确定您捕获的错误是测试中的预期错误,还是最终确定测试失败。只是一团糟。
答案 8 :(得分:0)
Chai static void Main(string[] args)
{
Test1 test1 = new Test1() { abbrv = "Test1", date = new DateTime(2017, 11, 12), completed = false };
Test1 test2 = new Test1() { abbrv = "Test2", date = new DateTime(2017, 12, 17), completed = false };
Test1 test5 = new Test1() { abbrv = "Test5", date = new DateTime(2017, 12, 12), completed = false };
Test2 test3 = new Test2() { abbrv = "Test1", date = new DateTime(2017, 11, 12), completed = false, abbrevName = "AbbrvName1" };
Test2 test4 = new Test2() { abbrv = "Test2", date = new DateTime(2017, 12, 12), completed = false, abbrevName = "AbbrvName2" };
List<Test1> listTest1 = new List<Test1>();
List<Test2> listTest2 = new List<Test2>();
List<Test2> listTest3 = new List<Test2>();
listTest1.Add(test1);
listTest1.Add(test2);
listTest1.Add(test5);
listTest2.Add(test3);
listTest2.Add(test4);
for (int i = 0; i < listTest1.Count; i++)
{
for (int a = 0; a < listTest2.Count; a++)
{
if (listTest1[i].abbrv == listTest2[a].abbrv && listTest1[i].date == listTest2[a].date)
{
if (!listTest3.Any(x => x.abbrv == listTest1[i].abbrv))
{
listTest3.Add(listTest2[a]);
}
}
else
{
if (listTest1[i].abbrv == listTest2[a].abbrv)
{
if (!listTest3.Any(x => x.abbrv == listTest1[i].abbrv && x.date != listTest1[i].date))
{
listTest3.Add(new Test.Test2() { abbrv = listTest2[a].abbrv, date = listTest2[a].date, completed = true, abbrevName = listTest2[a].abbrevName });
listTest3.Add(new Test.Test2() { abbrv = listTest1[i].abbrv, date = listTest1[i].date, completed = listTest1[i].completed, abbrevName = string.Empty });
}
}
else if (listTest1[i].abbrv != listTest2[a].abbrv)
{
if(!listTest3.Any(x => x.abbrv == listTest1[i].abbrv))
{
listTest3.Add(new Test.Test2() { abbrv = listTest1[i].abbrv, date = listTest1[i].date, completed = listTest1[i].completed, abbrevName = string.Empty });
}
}
}
}
}
}
public class Test1
{
public string abbrv { get; set; }
public DateTime date { get; set; }
public bool completed { get; set; }
}
public class Test2
{
public string abbrv { get; set; }
public DateTime date { get; set; }
public bool completed { get; set; }
public string abbrevName { get; set; }
}
(ES2016)
http://chaijs.com/api/bdd/#method_throw
为清楚起见...... 这工作
throw
这不起作用
it('Should fail if ...', done => {
let ret = () => {
MyModule.myFunction(myArg);
};
expect(ret).to.throw();
done();
});