NullInjectorError:MatDialogRef没有提供程序!角度测试

时间:2020-02-05 15:22:43

标签: angular jhipster angular-test testbed

我对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 */
}

然后我更新了测试文件:

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 */
});

我遇到的错误是:

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 [作为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/bundles/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/styleling/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/styleling/class_and_style_bindings.ts:1194:45) 在TestBedViewEngine.createComponent(node_modules/@angular/core/bundles/core-testing.umd.js:2648:56) 在Function.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) 在对象。 (node_modules / jest-preset-angular / zone-patch / index.js:51:54)

有什么主意吗?!

1 个答案:

答案 0 :(得分:4)

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

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

完整代码

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();
}));