Jest-preset-angular: Property 'toMatchSnapshot' does not exist on type 'Matchers'.

Created on 9 Apr 2019  路  12Comments  路  Source: thymikee/jest-preset-angular

I have configured jest with angular app using jest-preset-angular library and followed your documentation

However, I am still getting an error,

Property 'toMatchSnapshot' does not exist on type 'Matchers'.

Most helpful comment

based on @amojicamu idea, this works for me:

type JestExpect = (actual: R) => jest.Matchers<R> & jasmine.Matchers<R>;
declare const expect: JestExpect;

All 12 comments

This preset does not change anything on the jest types like Matcher.
Make sure the versions of @types/jest and jest match and try to narrow down the problem by e. g. setting quickly up a project without angular, but with TS and jest and see if the problem still exists.

I'm having the same issue.

Versions:
"jasmine-core": "~2.99.1"
"jest": "24.1.0"
"jest-preset-angular": "7.1.0"

It seems TS finds the expect definition from Jasmine and not Jest.

If I add add a global definition file (global.d.ts) at the application root.

import '@types/jest';

then expect resolves to jest.expect instead and the issue seems fixed, but all matchers from Jasmine are gone.

At the end of the day we have

On Jest
declare namespace jest { interface Matchers<R> { } }

On Jasmin
declare namespace jasmine { interface Matchers<T> { } }

I see some libraries do something like

declare global { namespace jasmine { interface Matchers<T> { } } }

Do you think there is an elegant way to merge both?

Oh I see. I think in general it is not recommended to use jasmine and jest.

I might be wrong but I think you can merge both in a custom type declaration.

Disclaimer: I did not test this, some changes might be necessary.

// jest-and-jasmine.d.ts

// taken from @types/jasmine/index.d.ts
// declare function expect(spy: Function): jasmine.Matchers<any>;
type JasmineExpect = (spy: Function) => jasmine.Matchers<any>;

declare const expect: jest.Expect | JasmineExpect;

TS should import it automatically if it is placed inside your src folder, but maybe you have to import it or declare it in typeRoots in tsconfig.json.

Thanks. I'll give it a try and let you know how it goes

Yes I think better removing everything about Jasmine, including jasmine types, jasmine-core, karma etc..

Thanks for your replies. I understand this is not an issue with jest-preset-angular. I though I would provide some more context and what I found out so far.

It is very common to use Jest together with Jasmine. Of course not Karma. Good news is it works very well.
Specially when testing NgRx effects, because jasmin-marbels is good for testing observables.
I'm doing something similar to this:

https://brianflove.com/2018/06/28/ngrx-testing-effects/

Here's how the NgRx project does it:

https://github.com/ngrx/platform/blob/master/projects/example-app/src/app/books/effects/book.effects.spec.ts

They don't add types and have expect be of type any.

I think it's very difficult to have typescript recognize both Matchers.

I tried this based @wtho suggestion:

type JasmineExpect = <T>(actual: T) => jasmine.Matchers<T>;

declare namespace jestJasmin {
    const expect: jest.Expect | JasmineExpect;
}

Still, TypeScript wont recognize both Matchers.

The easy way for now is to do

(<any>expect(result)).toMatchSnapshot();

That runs just fine even if the autocomplete experience is not optimal.

You can use rxjs-marbles instead btw as an alternative way https://github.com/cartant/rxjs-marbles . Besides, testing effects doesn't necessarily use marble diagram. You can simply define Effects module.forRoot in TestBed, dispatch action and your test environment is good to test any effects logic. I did it that way so I don't have to install extra package like jasmine-marbles or rxjs-marbles

Ok rxjs-marbles looks good.

I used the approach you outline for testing effects. The ones I'm testing right now are fairly complex and I need to assert on things like cancellation when events are dispatched in very specific frames (before mock API's finish i.e.) In this case I think a marbles approach is correct.

I'll try to move to rxjs marbles. Thanks for your feedback

based on @amojicamu idea, this works for me:

type JestExpect = (actual: R) => jest.Matchers<R> & jasmine.Matchers<R>;
declare const expect: JestExpect;

based on @amojicamu idea, this works for me:

type JestExpect = (actual: R) => jest.Matchers<R> & jasmine.Matchers<R>;
declare const expect: JestExpect;

But where did you put that lines ? :)

@timothyalcaide you can place it in any ts file in the scope of the project, e. g. in /src/test-types.ts. TypeScript will automatically pick up all declare statements.

Removing everything is the only way for it to work with all IDEs etc, unless you found a magic formula as it doesn't always pick up declare

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chris5287 picture chris5287  路  7Comments

Hotell picture Hotell  路  3Comments

gagle picture gagle  路  5Comments

r-kernberger picture r-kernberger  路  7Comments

maxencefrenette picture maxencefrenette  路  8Comments