Ionic 单元测试Angular独立组件,未使用覆盖提供程序

hgncfbus  于 2023-11-15  发布在  Ionic
关注(0)|答案(2)|浏览(150)

我有一个angular组件,使用了一个我想在单元测试中模拟的类。所以我在测试的provider-section中覆盖了它。但是组件仍然调用了真实的类,我得到了一个错误。
这在没有独立组件的旧项目中工作得很好,但我想我需要为独立组件做一些不同的事情?但我不知道该做什么:-(
我将其简化为这个测试用例:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule, ModalController } from '@ionic/angular';
import { BrowserModule } from '@angular/platform-browser';
import { Component } from '@angular/core';

// Dummy Standalone Component, just a single method that uses the ionic ModalController
@Component({
    selector: 'app-test-dialog',
    template: '',
    imports: [
        IonicModule
    ],
    standalone: true
})
export class TestDialogComponent {

    constructor(private modalCtrl: ModalController) {

    }

    async close() {
        await this.modalCtrl.dismiss();
    }

}

// Test, should override the dismiss method of the ModalController
describe('TestDialogComponent', () => {
    let component: TestDialogComponent;
    let fixture: ComponentFixture<TestDialogComponent>;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            imports: [
                BrowserModule,
                IonicModule.forRoot(),
                TestDialogComponent
            ],
            providers: [
                {
                    // provide our own ModalController
                    provide: ModalController, useValue: {
                        dismiss: () => Promise.resolve()
                    }
                }
            ]
        }).compileComponents();
        fixture = TestBed.createComponent(TestDialogComponent);
        component = fixture.componentInstance;
    });

    // this should call the provided mock class
    // but I get 'overlay does not exist thrown' 
    // because it calls the real method :-(
    it('close closes the dialog', async () => {
        const modalController = TestBed.inject(ModalController);
        const dismissSpy = spyOn(modalController, 'dismiss');
        await component.close();
        expect(dismissSpy).toHaveBeenCalled();
    });

});

字符串

jq6vz3qz

jq6vz3qz1#

要在测试中覆盖ModalController提供程序,请执行以下操作:

it('close closes the dialog', async () => {
  // Override the ModalController provider for the TestDialogComponent component
  TestBed.overrideComponent(TestDialogComponent, {
    providers: [
      {
        provide: ModalController,
        useValue: {
          dismiss: () => Promise.resolve()
        }
      }
    ]
  });

  // Create a fixture for the TestDialogComponent component
  const fixture = TestBed.createComponent(TestDialogComponent);
  const component = fixture.componentInstance;

  // Call the close method on the component
  await component.close();

  // Expect the dismiss method on the mock ModalController to have been called
  expect(spyOn(TestBed.inject(ModalController), 'dismiss')).toHaveBeenCalled();
});

字符串

2ledvvac

2ledvvac2#

我找到了以下解决方案。但我不明白为什么我需要在这种情况下,在其他情况下,覆盖的提供程序的工作...

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule, ModalController } from '@ionic/angular';
import { BrowserModule } from '@angular/platform-browser';
import { Component } from '@angular/core';

@Component({
    selector: 'app-test-dialog',
    template: '',
    imports: [
        IonicModule
    ],
    standalone: true
})
export class TestDialogComponent {

    constructor(private modalCtrl: ModalController) {

    }

    async close() {
        await this.modalCtrl.dismiss();
    }

}

// use a mock-class so we can directly spy on it
class ModalControllerMock {
    dismiss() {
        return Promise.resolve();
    }
}

describe('TestDialogComponent', () => {
    let component: TestDialogComponent;
    let fixture: ComponentFixture<TestDialogComponent>;
    const modalControllerMock = new ModalControllerMock();

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            imports: [
                BrowserModule,
                IonicModule.forRoot(),
                TestDialogComponent
            ]
        }).compileComponents();
        // use this provider instead of the provider in configureTestingModule
        TestBed.overrideComponent(TestDialogComponent, {
            set: {
                providers: [{  provide: ModalController, useValue: modalControllerMock}],
            },
        });
        fixture = TestBed.createComponent(TestDialogComponent);
        component = fixture.componentInstance;
    });

    it('close closes the dialog', async () => {
        const dismissSpy = spyOn(modalControllerMock, 'dismiss');
        await component.close();
        expect(dismissSpy).toHaveBeenCalled();
    });

});

字符串

相关问题