NullInjectorError:没有 MatDialogRef 的提供者!角度测试

Zak*_*HAM 4 testbed jhipster angular angular-test

我是 Angular 和 jhipster 的新手,我编辑了登录组件,添加了 formbuilder 和 MatDialogRef 并更新了单元测试:

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 */
}
Run Code Online (Sandbox Code Playgroud)

然后我更新了测试文件:

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 */
});
Run Code Online (Sandbox Code Playgroud)

我收到的错误是:

StaticInjectorError(DynamicTestModule)[JhiLoginModalComponent -> MatDialogRef]:StaticInjectorError(平台:核心)[JhiLoginModalComponent -> MatDialogRef]:NullInjectorError:没有MatDialogRef的提供者!在NullInjector.get(node_modules/@angular/core/bundles/core.umd.js:3083:7)在resolveToken(../packages/core/src/render3/context_discovery.ts:297:66)在tryResolveToken(. ./packages/core/src/render3/context_discovery.ts:285:2) 在 StaticInjector.get (../packages/core/src/render3/context_discovery.ts:279:55) 在resolveToken (../packages/ core/src/render3/context_discovery.ts:297:66) 在 tryResolveToken (../packages/core/src/render3/context_discovery.ts:285:2) 在 StaticInjector.get (../packages/core/src/ render3/context_discovery.ts:279:55)在resolveNgModuleDep(../packages/core/src/render3/instructions.ts:1032:26)在NgModuleRef_.get(node_modules/@angular/core/bundles/core.umd)。 js:6810:10895)在resolveDep(../packages/core/src/render3/instructions.ts:1116:55)在createClass(../packages/core/src/render3/instructions.ts:1091:13)在 createDirectiveInstance (../packages/core/src/render3/instructions.ts:1090:5) 在 createViewNodes (node_modules/@angular/core/bundles/core.umd.js:6967:2760) 在 createRootView (node_modules/@) Angular/core/bundles/core.umd.js:6967:280) 在 callWithDebugContext (node_modules/@angular/core/bundles/core.umd.js:7020:1250) 在 Object.debugCreateRootView [as createRootView] (node_modules/@ Angular/core/bundles/core.umd.js:6998:3227) 在 ComponentFactory_.create (node_modules/@angular/core/bundles/core.umd.js:6808:318) 在 initComponent (node_modules/@angular/core/)捆绑/ core-testing.umd.js:2644:45)在ZoneDelegate.invoke(node_modules/zone.js/dist/zone.js:440:160)在ProxyZoneSpec.onInvoke(node_modules/zone.js/dist/proxy)。 js:151:35) 在 ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:48) 在 Object.onInvoke (../packages/core/src/render3/styling/class_and_style_bindings.ts:1223 :6) 在 ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:48) 在 Zone.run (node_modules/zone.js/dist/zone.js:167:37) 在 NgZone.run ( ../packages/core/src/render3/styling/class_and_style_bindings.ts:1194:45) 在 TestBedViewEngine.createComponent (node_modules/@angular/core/bundles/core-testing.umd.js:2648:56) 在函数处。 TestBedViewEngine.createComponent(node_modules/@angular/core/bundles/core-testing.umd.js:2180:38)位于src/test/javascript/spec/app/shared/login/login.component.spec.ts:49: 25 在 ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:440:160) 在 ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:151:35) 在 ZoneDelegate.invoke (node_modules/ zone.js/dist/zone.js:440:48) 在 Zone.run (node_modules/zone.js/dist/zone.js:167:37) 在对象处。

大家有什么想法吗?

Mah*_*hdi 9

您在构造函数中使用 MatDialogRef,因此您应该在 spec.ts 中添加提供程序

        providers: [
        {provide: MatDialogRef, useValue: {}},
        {provide: MAT_DIALOG_DATA, useValue: []},
    ]
Run Code Online (Sandbox Code Playgroud)

完整代码

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();
}));
Run Code Online (Sandbox Code Playgroud)