Javascript测试框架Jasmine(四):自定义Matcher

来源:互联网 发布:国外数据分析公司 编辑:程序博客网 时间:2024/06/06 13:05

zz from:http://keenwon.com/1212.html


一个项目常常需要封装自定义的Matcher来在多个spec中使用,这次讲下怎么写兼容Jasmine的自定义Matcher。

自定义的Matcher从本质上讲是一个对比函数,它的函数名就是暴露给expect调用的名称,它接受actual 值和expected 值。这个函数会传入Jasmine作用域中,可以在beforeEach 中调用到。每次spec执行完后,都会把自定义Matchers卸载,下面看个简单例子:

  1. var customMatchers = {
  2. toBeGoofy: function(util, customEqualityTesters) {
  3. return {
  4. compare: function(actual, expected) {
  5. if (expected === undefined) {
  6. expected = '';
  7. }
  8.  
  9. var result = {};
  10. result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters);
  11.  
  12. if (result.pass) {
  13. result.message = "Expected " + actual + " not to be quite so goofy";
  14. } else {
  15. result.message = "Expected " + actual + " to be goofy, but it was not very goofy";
  16. }
  17.  
  18. return result;
  19. }
  20. };
  21. }
  22. };

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 的效果

  1. var customMatchers = {
  2. toBeGoofy: function(util, customEqualityTesters) {
  3. return {
  4. compare: function(actual, expected) {
  5. if (expected === undefined) {
  6. expected = '';
  7. }
  8. var result = {};
  9. result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters);
  10. if (result.pass) {
  11. result.message = "通过了,通过了,通过了...";
  12. } else {
  13. result.message = "没通过,没通过,没通过...";
  14. }
  15. return result;
  16. }
  17. };
  18. }
  19. };
  20.  
  21. describe("测试自定义错误信息", function() {
  22. beforeEach(function() {
  23. jasmine.addMatchers(customMatchers);
  24. });
  25.  
  26. it("这是个失败的测试", function() {
  27. expect({
  28. hyuk: 'gawrsh'
  29. }).toBeGoofy(123);
  30. });
  31. });

在线演示

再看看没有指定message 的效果:

  1. var customMatchers = {
  2. toBeGoofy: function(util, customEqualityTesters) {
  3. return {
  4. compare: function(actual, expected) {
  5. if (expected === undefined) {
  6. expected = '';
  7. }
  8. var result = {};
  9. result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters);
  10. return result;
  11. }
  12. };
  13. }
  14. };
  15.  
  16. describe("测试自动生成的错误信息", function() {
  17. beforeEach(function() {
  18. jasmine.addMatchers(customMatchers);
  19. });
  20.  
  21. it("这是个失败的测试", function() {
  22. expect({
  23. hyuk: 'gawrsh'
  24. }).toBeGoofy(123);
  25. });
  26. });

点击这里查看效果,可以看出,Jasmine把Matcher的名字,按照驼峰命名法分隔开,生成错误信息。

自定义“否定”比较规则

如果你的自定义Matcher需要控制.not 的行为的话(不是简单的布尔值取反),那么你的Matcher构造函数里除了compare ,还可以包含另一个函数negativeCompare 。当使用了.not 的时候会执行negativeCompare 。

Matcher的注册和使用

向Jasmine注册自定义的Matcher后,所有的expectation都可以使用该Matcher。

  1. describe("注册'toBeGoofy'", function() {
  2.  
  3. beforeEach(function() {
  4. jasmine.addMatchers(customMatchers);
  5. });
  6.  
  7. //...
  8.  
  9. });


– 下一篇讲一下Jasmine里比较牛的Spies –


阅读全文
0 0
原创粉丝点击