ng-mocks
ng-mocks copied to clipboard
Bug: ComponentStore observale not working with ng-mock >= 13.3.0
Description of the bug
Hi, I just migrated an angular project from version 12 to 13. Everything goes well except for ComponentStore (NGRX) tests. The observables complete directly, without emiting value.
For the context:
- Angular 13.3.11
- Jest 27.5.1
- @ngrx/component-store 13.2.0
- jest-marbles 3.0.2
I tested all versions of ng-mocks
to find the one that causes problems, and it's this one: 13.3.0
. Everything works before (ex 13.2.0
).
Do you have any idea of the modification that causes this?
Thanks
Minimal reproduction example:
ComponentStore to be tested:
@Injectable()
export class MyComponentStore extends ComponentStore<{ value: string }> {
constructor() {
super({ value: 'value' });
}
readonly values$ = this.select(({ value }) => value);
}
Failling test case:
describe('MyComponentStore', () => {
let componentStore: MyComponentStore;
beforeEach(() => MockBuilder(MyComponentStore));
beforeEach(() => {
componentStore = MockRender(MyComponentStore).point.componentInstance;
});
// This test no longer works with ng-mocks >= 13.3.0
it('should initial state and value', () => {
expect(componentStore.state$).toBeObservable(cold('a', { a: { value: 'value' } }));
expect(componentStore.values$).toBeObservable(cold('a', { a: 'value' }));
});
});
Working test case without jest-marble
:
describe('MyComponentStore', () => {
let componentStore: MyComponentStore;
beforeEach(() => MockBuilder(MyComponentStore));
beforeEach(() => {
componentStore = MockRender(MyComponentStore).point.componentInstance;
});
const testScheduler = new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
// However, this one works all the time (without jest-marble)
it('should have initial state', () => {
testScheduler.run((helpers) => {
const { expectObservable } = helpers;
expectObservable(componentStore.state$).toBe('a', { a: { value: 'value' } });
expectObservable(componentStore.values$).toBe('a', { a: 'value' });
});
});
});
It works fine without an ng-mocks
context (to show that it doesn't come from jest-marble
):
describe('MyComponentStore', () => {
let componentStore: MyComponentStore;
beforeEach(() => {
componentStore = new MyComponentStore();
});
// Work
it('should initial state and value', () => {
expect(componentStore.state$).toBeObservable(cold('a', { a: { value: 'value' } }));
expect(componentStore.values$).toBeObservable(cold('a', { a: 'value' }));
});
});
Expected vs actual behavior
Actual:
● MyComponentStore › should initial state and value
expect(received).toBeNotifications(expected)
Expected notifications to be:
[{"frame": 0, "notification": {"error": undefined, "kind": "N", "value": {"value": "value"}}}]
But got:
[{"frame": 0, "notification": {"error": undefined, "kind": "C", "value": undefined}}]
Expected: Test should passed
Hi there. Thanks for the report. I'll take a look, hopefully, this week.
The release: https://github.com/ike18t/ng-mocks/releases/tag/v13.3.0
Hi @kekel87, could you provide a min repo with the issue?
in my case I always get
TypeError: Cannot call a class as a function
at _classCallCheck (node_modules/@babel/runtime/helpers/esm/classCallCheck.js:3:1)
at new Observable (node_modules/rxjs/dist/esm/internal/Observable.js:9:28)
For now, I would assume it has root providers which are mocked by MockBuilder
.
Could you keep the related token? https://ng-mocks.sudo.eu/api/MockBuilder#ng_mocks_root_providers-token
Here is a minimal example of reproduction https://stackblitz.com/edit/github-ec7feu?file=package.json,src%2Ftest.spec.ts
I tested in Angular 14 before downgrading to Angular 13 in Stackblitz, and it seemed to work.
I did not know this token, I will try to test this afternoon.
Thanks
For me it's still,
Chrome Headless 103.0.5058.0 (Mac OS 10.15.7) issue-2862 should initial state and value FAILED
TypeError: Cannot call a class as a function
at _classCallCheck (node_modules/@babel/runtime/helpers/esm/classCallCheck.js:3:1)
at new Observable (node_modules/rxjs/dist/esm/internal/Observable.js:9:28)
at ColdObservable._createSuperInternal (node_modules/@babel/runtime/helpers/esm/createSuper.js:12:1)
at new ColdObservable (node_modules/rxjs/dist/esm/internal/testing/ColdObservable.js:8:9)
at TestScheduler.createColdObservable (node_modules/rxjs/dist/esm/internal/testing/TestScheduler.js:38:22)
at new TestColdObservable (node_modules/jasmine-marbles/es6/src/test-observables.js:10:32)
at cold (node_modules/jasmine-marbles/es6/index.js:9:12)
at UserContext.apply (src/issue-2862/test.spec.ts:29:11)
at _ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:409:30)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/zone-testing.js:303:43)
Ah, I think this is exactly the issue
Expected $[0].notification to be a kind of Object, but was Notification({ kind: 'N', value: 'value', error: undefined, hasValue: true }).
checking, thanks!
So far I can see the error on "target": "es5"
, whereas "target": "es2015"
works well. Could you share your tsconfig.json
?
Something is wrong: here I use [email protected]
(also I've tried 13.2.0), but it still fails: https://stackblitz.com/edit/github-ec7feu-pwtrks?file=src%2Ftest.spec.ts
Could you share here a zip or github repo where I could simply switch ng-mocks
from 13.3.0
to 13.2.0
and get different behavior?
Hi @kekel87, could you check what I'm missing?
Looks like it's something with Angular and es5 vs es2015.
I've created a repo without ng-mocks
and it still fails: https://github.com/satanTime/github-ec7feu-pwtrks/tree/classic
There is an example with ng-mocks
: https://github.com/satanTime/github-ec7feu-pwtrks
Sorry, I'm on vacation without a computer. I just followed the Angular CLI configuration for this. If you can't find a reason, we can just wait to upgrade to Angular 14 (where the problem doesn't arise).
Oki, have good vacation. Please, ping me when you are back.
Hi @kekel87, I hope this finds you well. Are you back to check my comments?
Hi @kekel87,
how is like? Did you have a change to take a look at my comment above?
Hi @kekel87,
any update on this?
So sorry.
I left the problem aside by setting the ng-mocks
version to 13.2.0
. We haven't migrated to Angular 14 yet. If we are the only ones to report the problem, maybe it's not worth spending time on it.
For the tsconfig.json
/tsconfig.spec.json
, we align with @angular/cli config, so is : "target": "es2017",
Sorry again for my late reply.
aha, with es2017
it works now. Can you try [email protected]
? It works with all Angular versions.
I've updates min examples:
no ng-mocks
- works well: https://github.com/satanTime/github-ec7feu-pwtrks/tree/classic
with [email protected]
- also works well: https://github.com/satanTime/github-ec7feu-pwtrks
it would be great if you had a chance to take a look why the second one doesn't fail.
Hi @kekel87, I'm going to close the issue. Feel free to reopen it when you have more info.