Javascript 测试框架 Jasmine(四):自定义 Matcher
2014-06-20 · 912 chars · 5 min read
一个项目常常需要封装自定义的 Matcher 来在多个 spec 中使用,这次讲下怎么写兼容 Jasmine 的自定义 Matcher。
自定义的 Matcher 从本质上讲是一个对比函数,它的函数名就是暴露给 expect 调用的名称,它接受actual
值和expected
值。这个函数会传入 Jasmine 作用域中,可以在beforeEach
中调用到。每次 spec 执行完后,都会把自定义 Matchers 卸载,下面看个简单例子:
var customMatchers = { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = '' } var result = {} result.pass = util.equals(actual.hyuk, 'gawrsh' + expected, customEqualityTesters) if (result.pass) { result.message = 'Expected ' + actual + ' not to be quite so goofy' } else { result.message = 'Expected ' + actual + ' to be goofy, but it was not very goofy' } return result }, } }, }
Matcher 构造函数#
自定义 Matcher 的构造函数接受两个参数,util
:给 Matcher 使用的一组工具函数;customEqualityTesters
:调用util.equals
的时候需要传入。
构造函数需要返回一个对象,这个对象要包含名为compare
的函数,执行 Matcher 时会调用compare
函数。
compare 函数#
compare
函数接收传入expect
的值作为它的第一个参数actual
,如果存在的话,传入 Matcher 自己的参数会作为compare
函数的第二个参数。上例中的toBeGoofy
就会接收一个可选的expected
参数,默认不需要传入。
Result#
compare
函数必须返回一个结果对象。结果对象必须包含一个布尔值类型的pass
属性,告诉 expectation Matcher 是否通过。如果 expectation 调用了.not
的话,会做相反的判断。上例中的toBeGoofy
测试实际值得hyuk
属性是否和期望值相等。
错误信息#
如果不指定错误信息,expectation 会尝试用 Matcher 生成一个错误信息。但是,如果返回的 result 对象包含了message
属性的话,会使用message
的值作错误提示。
先看看指定message
的效果
var customMatchers = { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = '' } var result = {} result.pass = util.equals(actual.hyuk, 'gawrsh' + expected, customEqualityTesters) if (result.pass) { result.message = '通过了,通过了,通过了...' } else { result.message = '没通过,没通过,没通过...' } return result }, } }, } describe('测试自定义错误信息', function () { beforeEach(function () { jasmine.addMatchers(customMatchers) }) it('这是个失败的测试', function () { expect({ hyuk: 'gawrsh', }).toBeGoofy(123) }) })
再看看没有指定message
的效果:
var customMatchers = { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = '' } var result = {} result.pass = util.equals(actual.hyuk, 'gawrsh' + expected, customEqualityTesters) return result }, } }, } describe('测试自动生成的错误信息', function () { beforeEach(function () { jasmine.addMatchers(customMatchers) }) it('这是个失败的测试', function () { expect({ hyuk: 'gawrsh', }).toBeGoofy(123) }) })
点击这里查看效果,可以看出,Jasmine 把 Matcher 的名字,按照驼峰命名法分隔开,生成错误信息。
自定义“否定”比较规则#
如果你的自定义 Matcher 需要控制.not
的行为的话(不是简单的布尔值取反),那么你的 Matcher 构造函数里除了compare
,还可以包含另一个函数negativeCompare
。当使用了.not
的时候会执行negativeCompare
。
Matcher 的注册和使用#
向 Jasmine 注册自定义的 Matcher 后,所有的 expectation 都可以使用该 Matcher。
describe("注册'toBeGoofy'", function () { beforeEach(function () { jasmine.addMatchers(customMatchers) }) //... })
– 下一篇讲一下 Jasmine 里比较牛的 Spies –