4

I'd need a replacement for the jasmine.addMatchers function gone in version 1.3. The current API allows to add matchers to a describe block, but I'd prefer to be able to use my matchers everywhere without adding them again and again.

Is there a global way to add own matchers to jasmine 3.1.0?

maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • Have you tried creating a module of the matchers and just instantiating them wherever you want to use them? – manAbl Jun 03 '18 at 01:23
  • @ManuelBlanco No, I actually don't have a clue how to do it. Anyway, I'd like my matchers to be available everywhere without any additional work, just like the build-in matchers are. – maaartinus Jun 03 '18 at 02:09

3 Answers3

3

https://github.com/JamieMason/add-matchers can be used to write matchers which work in all versions of Jasmine, as well as Jest.

var addMatchers = require('add-matchers');

addMatchers({
  // matcher with 0 arguments
  toBeEvenNumber: function(received) {
    // received : 4
    return received % 2 === 0;
  },
  // matcher with 1 argument
  toBeOfType: function(type, received) {
    // type     : 'Object'
    // received : {}
    return Object.prototype.toString.call(received) === '[object ' + type + ']';
  },
  // matcher with many arguments
  toContainItems: function(arg1, arg2, arg3, received) {
    // arg1     : 2
    // arg2     : 15
    // arg3     : 100
    // received : [100, 14, 15, 2]
    return (
      received.indexOf(arg1) !== -1 &&
      received.indexOf(arg2) !== -1 &&
      received.indexOf(arg3) !== -1
    );
  }
});
Jamie Mason
  • 4,159
  • 2
  • 32
  • 42
2

Note that I have not tried this in jasmine 3.1, but this is how I am doing the same in jasmine 2.8:

Place this in any code block that gets run before your tests:

jasmine.getEnv().beforeEach(() => {
  jasmine.addMatchers({
    toBeAwesome(util, customEqualityTesters) { ... }
  })
});
Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148
  • The question acknowledges this is possible ("The current API allows to add matchers to a describe block") and states that it is insufficient for purposes of the question ("I'd prefer to be able to use my matchers everywhere without adding them again and again"). – DavidW Jun 06 '18 at 20:28
  • This code does not need to be in a describe block. It can be anywhere, even be placed in the global scope if you like, as long as it is run before your tests. It is essentially creating a global `beforeEach` that is not tied to a single describe. So, technically, yes these matchers are still being added for each describe block, but for the purposes of your own code you only need to specify them once. – Andrew Eisenberg Jun 06 '18 at 21:57
  • This global `beforeEach` sounds hacky, but I guess, it'd do what I want. I've tried the other solution first and it it worked, so I'll stick with it. – maaartinus Jun 08 '18 at 14:02
  • This is a much better answer than `add-matcher` lib. `add-matcher` is awesome but doesn't allow you to customize failure messages like you can do with matchers written for Jasmine. Also you can swap `beforeAll` instead of `beforeEach` and it should be a little better. – Samuel Neff Jul 31 '19 at 03:59
  • And what file is this supposed to be written in? (remember all tests have random run-order) – Top-Master Oct 27 '21 at 08:43
0

With jasmine-core version 3.8 (possibly already with 3.1) the answer by Andrew Eisenberg no longer works. Therefore I have created a beforeAll() outside my tests (= outside of all describe-blocks), which is thereby executed before all tests.

If you work with Angular you can place it in src/test.ts.

Inside the beforeAll() I simply call jasmine.addMatchers(myCustomMatcher):

beforeAll(() => jasmine.addMatchers(myCustomMatcher));
Vasco
  • 418
  • 1
  • 8
  • 12