I have a simple need: to use my own custom matchers in Jasmine unit tests within an Angular CLI project (Angular v6). A couple constraints:
- I do not want to modify anything under node_modules; this project has to be able to go through my build pipeline which does a clean install every time.
- I do not want to have to build an npm module just to be able to add to
types
in tsconfig.spec.json.
What I have been able to discern so far is that I need a .d.ts file, so this is my matchers.d.ts:
/// <reference path="../../../node_modules/@types/jasmine/index.d.ts" />
declare namespace jasmine {
interface Matchers<T> {
toContainPath(path: string): boolean;
}
}
In the same directory I have my matchers.ts file:
export const customMatchers: jasmine.CustomMatcherFactories = {
// Affirms the element contains a sub-element at the given CSS path.
toContainPath: function (_util, _customEqualityTesters) {
return {
compare: function (element: HTMLElement, path: string) {
const result = {
pass: false,
message: ''
};
if (!element) {
result.message = 'Expected element to be non-empty';
} else if (!path) {
result.message = 'Expected path to be non-empty';
} else {
result.pass = element.querySelector(path) !== null;
result.message =
'Expected ' + element + (result.pass ? ' not' : '') + ' to contain ' + path;
}
return result;
}
};
}
};
In my test (spec) file, I have:
import { customMatchers } from 'app/testing/matchers';
. . .
/// <reference path="../../../testing/matchers.d.ts" />
. . .
beforeEach(() => {
jasmine.addMatchers(customMatchers);
. . .
and finally, I use the matcher in included tests with, e.g.:
expect(element).toContainPath('my-sidebar');
I also tried adding the full path of matchers.d.ts to the types
array in tsconfig.spec.json.
Alas, I have not been able to find a solution that works. The failure continues to manifest as
error TS2339: Property 'toContainPath' does not exist on type 'Matchers<HTMLElement>'
Promising places I looked, but to no avail:
- custom jasmine matchers
- adding a jasmine matcher TypeScript definition
- jasmine matchers
- testing Angular with custom matchers
- manually add typing file to TypeScript
Could anyone offer the secret sauce?
The two answers here combined ended up working for me!
Create custom jasmine matcher using Typescript
Added an index.ts to the testing folder and made the .ts and .d.ts files have different names (e.g. custom-matchers.ts and matchers-types.d.ts).