Is there a way to add a Jasmine matcher to the who

2019-02-02 20:14发布

问题:

There are plenty of documents that show how to add a matcher to a Jasmine spec (here, for example).

Has anyone found a way to add matchers to the whole environment; I'm wanting to create a set of useful matchers to be called by any and all tests, without copypasta all over my specs.

Currently working to reverse engineer the source, but would prefer a tried and true method, if one exists.

回答1:

Sure, you just call beforeEach() without any spec scoping at all, and add matchers there.

This would globally add a toBeOfType matcher.

beforeEach(function() {
  var matchers = {
    toBeOfType: function(typeString) {
      return typeof this.actual == typeString;
    }
  };

  this.addMatchers(matchers);
});

describe('Thing', function() {
  // matchers available here.
});

I've made a file named spec_helper.js full of things like custom matchers that I just need to load onto the page before I run the rest of the spec suite.



回答2:

Here's one for jasmine 2.0+:

beforeEach(function(){
  jasmine.addMatchers({
    toEqualData: function() {
      return {
        compare: function(actual, expected) {
          return { pass: angular.equals(actual, expected) };
        }
      };
    }
  });
});

Note that this uses angular's angular.equals.



回答3:

Edit: I didn't know it was an internal implementation that may be subjected to change. Use at your own risk.

jasmine.Expectation.addCoreMatchers(matchers)


回答4:

Based on previous answers, I created the following setup for angular-cli. I also need an external module in my matcher (in this case moment.js)

Note In this example I added an equalityTester, but it should work with a customer matcher

Create a file src/spec_helper.ts with the following contents:

// Import module
import { Moment } from 'moment';

export function initSpecHelper() {

  beforeEach(() => {
    // Add your matcher
    jasmine.addCustomEqualityTester((a: Moment, b: Moment) => {
      if (typeof a.isSame === 'function') {
        return a.isSame(b);
      }
    });
  });

}

Then, in src/test.ts import the initSpecHelper() function add execute it. I placed it before Angular's TestBed init, wich seems to work just fine.

import { initSpecHelper } from './spec_helper';

//...

// Prevent Karma from running prematurely.
__karma__.loaded = function () {};

// Init our own spec helper
initSpecHelper();

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);

//...