【问题标题】:Angular Unit Testing on a component async / await function in jasmine茉莉花中组件异步/等待功能的角度单元测试
【发布时间】:2020-02-06 09:42:22
【问题描述】:

我想测试服务返回的对象是否调用了特定的方法。

组件方法是async,因为服务将返回Promise

这是组件代码。

// component
export class FilterComponent {
  constructor(
    private modalController: ModalController,
  ) { }

  async onFilterClicked() {
    const modal = await this.modalController.create({
      component: FilterModalPage,
    });

    modal.onDidDismiss().then(res => {
      if (res.data) {
        // do something
      }
    });

    await modal.present();
  }
}

这是我的测试

describe('FilterComponent', () => {
  let fixture: ComponentFixture<FilterComponent>;
  let component: FilterComponent;
  let modalControllerSpy;
  let modalSpy;

  beforeEach(async () => {
    modalControllerSpy = jasmine.createSpyObj('modalController', ['create']);
    modalSpy = jasmine.createSpyObj('modal', ['present']);

    TestBed.configureTestingModule({
      declarations: [FilterComponent],
      providers: [
        { provide: ModalController, useValue: modalControllerSpy },
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FilterComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  describe('onFilterClicked', () => {
    it('should `present` the modal', () => {
      modalControllerSpy.create.and.returnValue(modalSpy);

      component.onFilterClicked();
      fixture.detectChanges();

      expect(modalControllerSpy.create).toHaveBeenCalled(); // success
      expect(modalSpy.present).toHaveBeenCalled(); // fail :( how to test `present` is called????
    });
  });
});

我在第一个 beforeEach 回调中创建了 spy 对象。

modalControllerSpy = jasmine.createSpyObj('modalController', ['create']);
modalSpy = jasmine.createSpyObj('modal', ['present']);

我想测试我的modalSpy 是否调用present 函数。 也许我在这里做错了什么。

【问题讨论】:

  • 你检查过任何答案吗?任何反馈将不胜感激。

标签: angular typescript unit-testing jasmine


【解决方案1】:

create() 的返回值需要是一个承诺。请尝试以下操作:

it('should `present` the modal', () => {
  modalControllerSpy.create.and.returnValue(Promise.resolve(modalSpy));

  component.onFilterClicked();
  fixture.detectChanges();

  expect(modalControllerSpy.create).toHaveBeenCalled(); // success
  expect(modalSpy.present).toHaveBeenCalled(); // should pass now
});

请参阅文档here

【讨论】:

    【解决方案2】:

    我将重构测试套件如下:

    // ...
    // create a valid response for ModalController#create according to the logic in controller where it is used
    const modalObj = {
      onDidDismiss: () => Promise.resolve({ res: { data: 'test-value1' } })
    };
    
    // ...
    beforeEach(async () => {
      // create a spy object with the methods you want to spy on
      modalControllerSpy = jasmine.createSpyObj('ModalController', ['create', 'present']);
    
      // mock the returned value from the service
      modalControllerSpy.create.and.returnValue(modalObj);
      modalControllerSpy.present.and.returnValue(Promise.resolve('test-value2'));
    
      TestBed.configureTestingModule({
        declarations: [FilterComponent],
        providers: [
          { provide: ModalController, useValue: modalControllerSpy },
        ]
      }).compileComponents();
    });
    // ... 
      it('should `present` the modal', () => {
        component.onFilterClicked();
        fixture.detectChanges();   // maybe you don't need this, check if the test passes without it
    
        expect(modalControllerSpy.create).toHaveBeenCalled();
        expect(modalControllerSpy.present).toHaveBeenCalled();
        // you could add some additional checks here regarding to the returned values
        // in the promises since they were mocked: 'test-value1' and 'test-value2'
      });
    });
    // ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-19
      • 2016-06-14
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多