NullInjectorError: No provider for MatDialogRef! Angular Test
Asked Answered
I

1

5

I'm new to angular and jhipster, I've edited the login component and I've added the formbuilder and MatDialogRef and update the Unit test:

import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
/* Other imports */

@Component({
  selector: 'jhi-login-modal',
  templateUrl: './login.component.html',
  styleUrls: ['login.scss']
})
export class JhiLoginModalComponent implements OnInit {
  authenticationError: boolean;
  hide = true;
  loginForm: FormGroup;

  constructor(
    private readonly eventManager: JhiEventManager,
    private readonly loginService: LoginService,
    private readonly stateStorageService: StateStorageService,
    private readonly router: Router,
    private readonly fb: FormBuilder,
    private readonly dialogRef: MatDialogRef<JhiLoginModalComponent>
  ) {}

  ngOnInit(): void {
    this.loginForm = this.fb.group({
      username: ['', Validators.required],
      password: ['', Validators.required],
      rememberMe: true
    });
  }
 /* Rest of code */
}

Then i updated the test file:

import {ComponentFixture, TestBed, async, inject, fakeAsync, tick} from '@angular/core/testing';
import {FormBuilder, ReactiveFormsModule, Validators} from '@angular/forms';
import {JhiEventManager} from 'ng-jhipster';
import {JhiLoginModalComponent} from 'app/shared/login/login.component';
import {StateStorageService} from 'app/core/auth/state-storage.service';
import {BatimentTestModule} from '../../../test.module';
import {MockLoginService} from '../../../helpers/mock-login.service';
import {MockStateStorageService} from '../../../helpers/mock-state-storage.service';
import {MatDialogModule, MatDialogRef} from '@angular/material/dialog';


describe('Component Tests', () => {
  describe('LoginComponent', () => {
    let comp: JhiLoginModalComponent;
    let fixture: ComponentFixture<JhiLoginModalComponent>;
    // create new instance of FormBuilder
    const formBuilder: FormBuilder = new FormBuilder();
    let mockLoginService: any;
    let mockStateStorageService: any;
    let mockRouter: any;
    let mockEventManager: any;
    let mockActiveModal: any;

    beforeEach(async(() => {
      TestBed.configureTestingModule({
        imports: [BatimentTestModule, ReactiveFormsModule, MatDialogModule],
        declarations: [JhiLoginModalComponent],
        providers: [
          {
            provide: LoginService,
            useClass: MockLoginService
          },
          {
            provide: StateStorageService,
            useClass: MockStateStorageService
          },
          {
            provide: FormBuilder,
            useValue: formBuilder
          },
          {provide: MatDialogRef,
            useValue: {}}
        ]
      })
        .overrideTemplate(JhiLoginModalComponent, '')
        .compileComponents();
    }));

    beforeEach(() => {
      fixture = TestBed.createComponent(JhiLoginModalComponent);
      comp = fixture.componentInstance;
      console.log(comp);
      comp.loginForm = formBuilder.group({
        username: ['', Validators.required],
        password: ['', Validators.required],
        rememberMe: true
      });
      comp.ngOnInit();
      fixture.detectChanges();
      mockLoginService = fixture.debugElement.injector.get(LoginService);
      mockStateStorageService = fixture.debugElement.injector.get(StateStorageService);
      mockRouter = fixture.debugElement.injector.get(Router);
      mockEventManager = fixture.debugElement.injector.get(JhiEventManager);
      mockActiveModal = fixture.debugElement.injector.get(NgbActiveModal);
    });

    it('should authenticate the user upon login when previous state was set', inject(
      [],
      fakeAsync(() => {
        // GIVEN
        const credentials = {
          username: 'admin',
          password: 'admin',
          rememberMe: true
        };

        comp.loginForm.patchValue({
          username: 'admin',
          password: 'admin',
          rememberMe: true
        });
        mockLoginService.setResponse({});
        mockStateStorageService.setResponse('admin/users?page=0');

        // WHEN/
        comp.login();
        tick(); // simulate async

        // THEN
        expect(comp.authenticationError).toEqual(false);
        expect(mockActiveModal.dismissSpy).toHaveBeenCalledWith('login success');
        expect(mockEventManager.broadcastSpy).toHaveBeenCalledTimes(1);
        expect(mockLoginService.loginSpy).toHaveBeenCalledWith(credentials);
        expect(mockStateStorageService.getUrlSpy).toHaveBeenCalledTimes(1);
        expect(mockStateStorageService.storeUrlSpy).toHaveBeenCalledWith(null);
        expect(mockRouter.navigateByUrlSpy).toHaveBeenCalledWith('admin/users?page=0');
      })
    ));
 /* Other tests */
});

error i'm getting is:

StaticInjectorError(DynamicTestModule)[JhiLoginModalComponent -> MatDialogRef]: StaticInjectorError(Platform: core)[JhiLoginModalComponent -> MatDialogRef]: NullInjectorError: No provider for MatDialogRef! at NullInjector.get (node_modules/@angular/core/bundles/core.umd.js:3083:7) at resolveToken (../packages/core/src/render3/context_discovery.ts:297:66) at tryResolveToken (../packages/core/src/render3/context_discovery.ts:285:2) at StaticInjector.get (../packages/core/src/render3/context_discovery.ts:279:55) at resolveToken (../packages/core/src/render3/context_discovery.ts:297:66) at tryResolveToken (../packages/core/src/render3/context_discovery.ts:285:2) at StaticInjector.get (../packages/core/src/render3/context_discovery.ts:279:55) at resolveNgModuleDep (../packages/core/src/render3/instructions.ts:1032:26) at NgModuleRef_.get (node_modules/@angular/core/bundles/core.umd.js:6810:10895) at resolveDep (../packages/core/src/render3/instructions.ts:1116:55) at createClass (../packages/core/src/render3/instructions.ts:1091:13) at createDirectiveInstance (../packages/core/src/render3/instructions.ts:1090:5) at createViewNodes (node_modules/@angular/core/bundles/core.umd.js:6967:2760) at createRootView (node_modules/@angular/core/bundles/core.umd.js:6967:280) at callWithDebugContext (node_modules/@angular/core/bundles/core.umd.js:7020:1250) at Object.debugCreateRootView [as createRootView] (node_modules/@angular/core/bundles/core.umd.js:6998:3227) at ComponentFactory_.create (node_modules/@angular/core/bundles/core.umd.js:6808:318) at initComponent (node_modules/@angular/core/bundles/core-testing.umd.js:2644:45) at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:160) at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:151:35) at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:48) at Object.onInvoke (../packages/core/src/render3/styling/class_and_style_bindings.ts:1223:6) at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:48) at Zone.run (node_modules/zone.js/dist/zone.js:167:37) at NgZone.run (../packages/core/src/render3/styling/class_and_style_bindings.ts:1194:45) at TestBedViewEngine.createComponent (node_modules/@angular/core/bundles/core-testing.umd.js:2648:56) at Function.TestBedViewEngine.createComponent (node_modules/@angular/core/bundles/core-testing.umd.js:2180:38) at src/test/javascript/spec/app/shared/login/login.component.spec.ts:49:25 at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:160) at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:151:35) at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:48) at Zone.run (node_modules/zone.js/dist/zone.js:167:37) at Object. (node_modules/jest-preset-angular/zone-patch/index.js:51:54)

any idea guys ?!

Informative answered 5/2, 2020 at 15:22 Comment(1)
As JHipster does not use angular material, what have you done to include it into your project? You probably forgot something.Powerboat
A
10

You use MatDialogRef in constructor so you should add provider in spec.ts

        providers: [
        {provide: MatDialogRef, useValue: {}},
        {provide: MAT_DIALOG_DATA, useValue: []},
    ]

full code

import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material';
//...

    beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [JhiLoginModalComponent],
        imports: [
            TranslateModule.forRoot(),
            MatDialogModule,
            BrowserDynamicTestingModule
        ],
        providers: [
            {provide: MatDialogRef, useValue: {}},
            {provide: MAT_DIALOG_DATA, useValue: []},
        ]
    })
        .compileComponents();
}));
Apiarian answered 20/1, 2021 at 12:50 Comment(1)
answer works fine but I dont get it why, may you add some more details of the root cause for beginners like me?Revealment

© 2022 - 2024 — McMap. All rights reserved.