Skip to content

Directives cannot be mocked anymore #225

@floisloading

Description

@floisloading

Since updating to Angular 14.2.0, all Shallow-specs for Components with Directives in their temlates are failing with this message:

Error: NG0202: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
error properties: Object({ code: 202 })

Complete console output of ng test

✔ Browser application bundle generation complete.
15 09 2022 17:29:00.958:WARN [karma]: No captured browser, open http://localhost:9876/
15 09 2022 17:29:01.094:INFO [karma-server]: Karma v6.4.0 server started at http://localhost:9876/
15 09 2022 17:29:01.095:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
15 09 2022 17:29:01.098:INFO [launcher]: Starting browser Chrome
15 09 2022 17:29:03.625:INFO [Chrome 105.0.0.0 (Mac OS 10.15.7)]: Connected on socket -8NYow9oZdd_-iePAAAB with id 17397697
Chrome 105.0.0.0 (Mac OS 10.15.7) AppComponent should create FAILED
	Error: NG0202: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
	This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

	Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
	error properties: Object({ code: 202 })
	Error: NG0202: This constructor is not compatible with Angular Dependency Injection because its dependency at index 0 of the parameter list is invalid.
	This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.
	Please check that 1) the type for the parameter at index 0 is correct and 2) the correct Angular decorators are defined for this class and its ancestors.
	    at ɵɵinvalidFactoryDep (node_modules/@angular/core/fesm2020/core.mjs:4798:11)
	    at NodeInjectorFactory.factory (ng:///MockOfTestDirective/ɵfac.js:4:47)
	    at getNodeInjectable (node_modules/@angular/core/fesm2020/core.mjs:3523:44)
	    at instantiateAllDirectives (node_modules/@angular/core/fesm2020/core.mjs:12689:27)
	    at createDirectivesInstances (node_modules/@angular/core/fesm2020/core.mjs:12113:5)
	    at ɵɵelementStart (node_modules/@angular/core/fesm2020/core.mjs:15243:9)
	    at ɵɵelement (node_modules/@angular/core/fesm2020/core.mjs:15298:5)
	    at templateFn (ng:///AppComponent.js:371:9)
	    at executeTemplate (node_modules/@angular/core/fesm2020/core.mjs:12084:9)
	    at renderView (node_modules/@angular/core/fesm2020/core.mjs:11906:13)
Chrome 105.0.0.0 (Mac OS 10.15.7): Executed 2 of 2 (1 FAILED) (0.107 secs / 0.098 secs)
TOTAL: 1 FAILED, 1 SUCCESS

Output of ng version

Angular CLI: 14.2.2
Node: 16.17.0
Package Manager: npm 8.19.2
OS: darwin x64

Angular: 14.2.2
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1402.2
@angular-devkit/build-angular   14.2.2
@angular-devkit/core            14.2.2
@angular-devkit/schematics      14.2.2
@schematics/angular             14.2.2
rxjs                            7.5.6
typescript                      4.7.4

Minimal reproduction of the problem

ng new shallow-test --defaults
cd shallow-test
ng generate directive test
echo "<div appTest></div>" >> src/app/app.component.html
npm i --save-dev shallow-render

Paste this into app.component.spec.ts:

import { Shallow } from 'shallow-render';
import { AppComponent } from './app.component';
import { AppModule } from './app.module';

describe('AppComponent', () => {
  let shallow: Shallow<AppComponent>;

  beforeEach(() => {
    shallow = new Shallow(AppComponent, AppModule);
  });

  it('should create', async () => {
    const { instance } = await shallow.render();
    expect(instance).toBeTruthy();
  });
});

And execute ng test

Workaround

The only solution I found is to not mock it at all:

  beforeEach(() => {
    shallow = new Shallow(AppComponent, AppModule).dontMock(TestDirective);
  });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions