当前位置: 首页 > 后端技术 > Node.js

【Nodeassertassert】

时间:2023-04-03 23:00:53 Node.js

1.简介断言是一个编程术语,表示为一些布尔表达式,程序员认为在程序的某一点表达式的值是真的,可以随时启用和禁用断言验证,因此可以为测试启用断言,为部署禁用断言。同样,在程序上线后,如果最终用户遇到问题,他们可以重新启用断言。使用断言可以创建更稳定、质量更好且不易出错的代码。当一个值为FALSE时需要中断当前操作时,可以使用断言。[单元测试]必须使用断言。Node提供了10多个断言测试函数来测试不变量。为了便于理解和记忆,我将这10多个函数归类在了文章中。【提示】本文expected表示期望值,actual表示实际值,message表示自定义信息2.判断value是否为真有两个断言测试函数如下2.1assert(value[,message])这个测试函数在[Boolean(value)]为[true]时通过断言测试,否则抛出[AssertionError]constassert=require("assert");assert("blue","ThefirstvalueisWhenitisfalse,错误信息随我抛出");assert(true,"当第一个值为false时,错误信息随我抛出");上面的代码都是真的,因为[Boolean(value)]都是通过断言测试assert(false,"当第一个值为false时,把我当成错误信息丢给我");//AssertionError[ERR_ASSERTION]:当第一个值为false时,将我作为上面代码中的错误信息值抛出如果为false,则会抛出一个带有message属性的[AssertionError],其中message属性的值为等于传入消息参数的值。[如果未定义消息参数,将分配默认错误消息]。assert(false);//AssertionError[ERR_ASSERTION]:false==true由于上面代码没有指定[message]参数,所以抛出的是默认的错误信息[AssertionError]2.2assert.ok(value[,message])断言。ok()和assert()的功能一样,都是测试[value]是否为真。并且用法相同,所以assert()可以看作是assert.ok()的语法糖constassert=require("assert");assert.ok(true);assert.ok(1);上面的代码[Boolean(value)]都是真的,所以所有的断言都通过了。下面是断言失败的情况,分别列出默认的错误信息assert.ok(0);//AssertionError[ERR_ASSERTION]:0==trueassert.ok(false);//AssertionError[ERR_ASSERTION]:false==trueassert.ok(false,"customerrormessage");//AssertionError[ERR_ASSERTION]:customerrormessage3.判断期望值等于实际值(==)这个有两个测试函数合二为一组,用于检验期望值是否等于实际值。如果它们相等,则断言通过,否则[AssertionError]被抛出。3.1assert.equal(actual,expected[,message])assert.equal()用于测试期望值和实际值是否相等。【值类型比较两个值是否相等时,期望值和实际值是引用类型时比较值得参考】assert.equal(1,1);assert.equal("1",1);上面的代码是对值类型的比较,说明equal()内部使用的是(==),而不是严格相等。后面会总结严格相等equal(===)assert.equal({},{},"AssertionError");assert.equal(()=>{},()=>{},"AssertionError");assert.equal([],[],'AssertionError');以上三个表达式会抛出一个属性值为'AssertionError'[AssertionError]的[message]对象,[所以当值为引用类型时,equal()比较的是值得引用的值,所以两个值ofreferencetypescannotbeassertedthroughequal()]constobj={};assert.equal(obj,obj);//通过上面代码断言比较的是同一个对象,两个值领先使用相等,所以断言通过3.2assert.deepEqual(actual,expected[,message])也测试期望值和实际值是否相等,使用(==),但不同于equal,[deepEqual()比较时引用类型,比较的不是对值的引用,而是被比较对象的属性值]consta='Blue',b='Pink';assert.deepEqual(a,a,'actualunequaltoexpected');//assertthroughassert.deepEqual(a,b,'actualunequaltoexpected');//AssertionError[ERR_ASSERTION]:actualunequaltoexpected以上是值类型的比较,equal()确实没有任何区别constobj1={name:"foo",gender:"men"},obj2={name:"foo",gender:"men"},obj3={name:"bar",gender:"men"}assert.deepEqual(obj1,obj2,'actualunequaltoexpected');//Assertionpassedassert.deepEqual(obj1,obj3,'actualunequaltoexpected');//AssertionError[ERR_ASSERTION]:actualunequaltoexpected以上代码它是引用类型的比较。可以看出,[deepEqual()]比较的是属性值,而不是引用,这一点与equal()不同。【注意!!】deepEqual()只测试可枚举的自身属性,不测试对象的原型、连接器或不可枚举的属性(在这些情况下,使用assert.deepStrictEqual(),后面会总结)constson1=Object.create(obj1),son2=Object.create(obj2);son1.name="Summer";son2.name="Summer";assert.deepEqual(son1,son2,"actualunequaltoexpected");//上面通过的assert代码中,son1和son2分别继承了两个不同的对象,两者都有名为“Summer”的属性,最后结果通过,说明【deepEqual()没有测试对象的原型】constena={},enb={};Object.defineProperties(ena,{name:{value:"Blue"},hobby:{value:"foo",enumerable:false//enumerable设置为false}});Object.defineProperties(enb,{name:{value:"Blue"},hobby:{value:"bar",enumerable:false//setenumerabilitytofalse}})assert.deepEqual(ena,enb,"actualunequaltoexpected")//ok,actualequaltoexpected在上面的代码中,ena和enb用于同一个可枚举属性[name],具有不同取值的非可枚举属性[hobby],说明[deepEqual()不测试对象的不可枚举属性引用的属性]4.判断thattheexpectedvalueandactualvalueiscongruent(===)这组测试函数是用来深度判断期望值和实际值是否相等,内部使用的是(===),所以objectPrototypes也会被比较,valuetypes也会被scoped进行比较。该组还有两个测试函数。4.1assert.deepStrictEqual(actual,expected[,message])由于内部使用同余(===),所以对象的原型也会被纳入比较范围constobj1={name:"foo",gender:“男人”},obj2={名称:“酒吧”,性别:“男人”}constson1=Object.create(obj1),son2=Object.create(obj2);son1.name=“夏天”;son2.name="Summer";assert.deepEqual(son1,son2,"actualunequaltoexpected");//断言通过assert.deepStrictEqual(son1,son2,"actualunequaltoexpected")//AssertionError[ERR_ASSERTION]:actualunequalto上面预期的代码使用deepEqual()和deepStrictEqual()进行断言测试,son1和son2分别继承自两个不同的对象,但是具有相同的属性值。可以看出【deepEqual()没有考虑对象的原型,deepStrictEqual()包括原型对象作为比较对象】4.2assert.strictEqual(actual,expected[,message])strictEqual()是一个增强equal(),考虑数据类型;如果预期实际===,则断言通过,否则抛出AssertionError,消息?message:默认的错误信息。assert.strictEqual(1,2);//抛出AssertionError:1===2assert.strictEqual(1,1);//测试通过。assert.strictEqual(1,'1');//ThrowAssertionError:1==='1'assert.equal(1,'1');//测试通过。【暗示!!】引用类型永远不会通过【strictEqual()】断言测试5.判断期望值和实际值不相等(!=)以上总结了期望值和实际值相等的判断。这里总结一下判断期望值和实际值。两个测试函数等,其实就是上面(3)的逆运算。5.1assert.notEqual(actual,expected[,message])[notEqual()]是[equal()]的逆运算。如果actual!=expected,则断言通过。同样,对于值类型,只是比较值,对应的引用类型比较值得引用assert.notEqual("1","2");//Assertedviaassert.notEqual("1",2);//Assertedviaassert.notEqual("1",1);//AssertionError[ERR_ASSERTION]:'1'!=1上面的代码是比较值类型,第三个表达式的默认信息可以看出(!=)assert.notEqual({a:"foo"},{a:"foo"});assert.notEqual(()=>{},()=>{});assert.notEqual([],[]);上面的代码是针对引用类型[notEqual()]的断言测试是两个对象通过测试的[常量建立]的结果。5.2assert.notDeepEqual(actual,expected[,message])[notDeepEqual()]是[deepEqual()]的逆运算。如果actual!=expected,则断言通过。与notEqual()不同的是,它是对引用类型的值做判断,不比较原型和不可枚举属性,只比较自身的可枚举属性,断言通过。constobj1={a:"foo"},obj2={b:"bar"},obj3=Object.create(obj1);assert.notDeepEqual(obj1,obj1,'actualequaltoexpected');//AssertionError[ERR_ASSERTION]:actualequaltoexpectedassert.notDeepEqual(obj1,obj2,'actualequaltoexpected');//断言通过assert.notDeepEqual(obj1,obj3,'actualequaltoexpected');//断言结束时通过上面的代码一个表达式断言通过,说明【不比较原型,不可枚举属性,只比较自枚举属性】【注意!!】与notEqual的区别,即deepEqual和equal的区别,在引用数据类型时,deepEqual是比较值而不是引用,equal比较的是引用,所以引用类型永远不能通过相等时的断言测试等等,当引用类型不等于时,它永远无法通过断言测试。六。判断期望值和实际值严格不相等(!==)以上总结了期望值和实际值严格相等的判断。这里总结一下判断期望值和实际值严格不相等的两个测试函数。其实就是上面(4)的逆运算。6.1assert.notStrictEqual(actual,expected[,message])如果actual和expected不是!==,断言通过,与assert.deepStrictEqual()相反assert.notStrictEqual("1",1);//断言通过assert.notStrictEqual("1","1");//AssertionError[ERR_ASSERTION]:'1'!=='1'以上代码是对值类型的断言测试。可以看出[notStrictEqual()]考虑的是数据类型assert.notStrictEqual({a:"foo"},{a:"foo"});assert.notStrictEqual(()=>{},()=>{});assert.notStrictEqual([],[]);上面的代码是对引用类型的测试,全部通过,上面的表达式总是通过。6.2assert.notDeepStrictEqual(actual,expected[,message])notDeepStrictEqual()是deepStrictEqual()的逆运算,如果是的话!==预期,断言通过,否则抛出AssertionError。assert.notDeepStrictEqual({a:'1'},{a:1});//断言通过assert.notDeepStrictEqual({a:'1'},{a:"1"});//AssertionError[ERR_ASSERTION]:{a:'1'}notDeepStrictEqual{a:'1'}七。断言和抛出错误这组四个(可以说是三个)测试函数处理错误。7.1assert.fail(message)这个测试函数就不多说了,可以看成是对next函数的重载,用来主动抛出具有[message]属性的[AssertionError]对象assert.fail("customerrormessage");//AssertionError[ERR_ASSERTION]:Customerrormessage7.2assert.fail(actual,expected[,message[,operator[,stackStartFunction]]])该测试函数用于主动抛出自定义错误信息,throw错误信息格式:[实际参数+运算符参数+预期参数]assert.fail("BLUE","PINK");//AssertionError[ERR_ASSERTION]:'BLUE'!='PINK'上面代码没有提供[message]和[operator],则[operator]默认为[!=]assert.fail("BLUE","PINK","自定义错误信息");//AssertionError[ERR_ASSERTION]:自定义错误信息assert.fail("BLUE","PINK","自定义错误信息","?",()=>{console.log("hello");});//AssertionError[ERR_ASSERTION]:自定义错误信息上面代码提供了[message],此时[actual]、[operator]、[expected]等参数会被包含在错误对象属性中assert.fail("BLUE","PINK",undefined);//AssertionError[ERR_ASSERTION]:'BLUE'undefined'PINK'assert.fail("BLUE","PINK",undefined,"?");//AssertionError[ERR_ASSERTION]:'BLUE'?'PINK'上面的代码是[message]isundefined当检测到[operator]参数时,[operator?operator:undefined]7.3assert.throws(block,error,message)参数说明:blockerror|<功能>消息<任何>[描述!!】如果block抛出的错误满足error参数,即抛出的错误与预期一致,则断言通过,否则抛出block中的错误,如果block不抛出错误,则[断言错误][提示!!]错误参数可以是构造函数、正则表达式或自定义函数。assert.throws(()=>{thrownewError('错误信息');},错误);上述代码中,error参数为构造函数,[block]抛出的错误与预期一致,故断言通过。assert.throws(()=>{thrownewError('错误信息');},/error/);上面代码中的error参数是正则表达式,[block]抛出的错误满足正则表达式,所以assertpass。【注意!!】错误参数不能为字符串。如果第二个参数是字符串,则视为省略错误参数,将传递的字符串作为[message]参数,//这是错误的!不要这样做!assert.throws(myFunction,'errormessage','didnotthrowexpectedmessage');//应该这样做。assert.throws(myFunction,/errorinformation/,'没有抛出预期的信息');下面的代码,[error]参数是自定义函数assert.throws(()=>{thrownewError('errorinformation');},function(err){if((errinstanceofError)&&/error/.test(err)){returntrue;}},'不是预期的错误');7.4assert.doesNotThrow(block,error,message)【说明!!】当预期错误与实际错误一致时,不会抛出实际错误,而是抛出AssertionError。如果不一致,将抛出实际的错误信息assert.doesNotThrow(()=>{thrownewTypeError('errormessage');},SyntaxError);上面的例子会抛出TypeError因为没有匹配的错误类型assert.doesNotThrow(()=>{thrownewTypeError('errormessage');},TypeError);上面的例子会抛出一个Gotunwantedexception(TypeError)错误。//ThrowAssertionError:Gotunwantedexception(TypeError).抛出错误上面的代码表明:如果抛出一个AssertionError,并且给message参数传递了一个值,那么message参数的值会被添加到AssertionError的信息中8.判断该值是否为true只有一个这里测试函数8.1assert.ifError(value)如果value的值为true或者可以转换为true,则抛出value,否则断言通过。assert.ifError(true);//Throwtrueassert.ifError(false);//通过上面代码中直接给出的Boolean类型值进行Assert,如果值为true则抛出该值,否则什么都不做assert.ifError(0);//Assertionpassedassert.ifError("0");//Throw"0"assert.ifError(1);//Throw1assert.ifError(newError());//ThrowError,对象名以上所有代码在布尔(值)转换后进行测试。利用这个特性,我们可以使用这个测试函数来测试回调函数的错误参数。-------------结尾---------------CSDN【节点断言assert】同步更新