Угловое модульное тестирование асинхронной / ожидающей функции компонента в жасмине - PullRequest
2 голосов
/ 09 октября 2019

Я хотел проверить, вызывает ли объект, возвращаемый службой, определенный метод.

Метод компонента - 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 обратном вызове.

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

Я хотелпроверить, вызывает ли моя modalSpy функция present. Возможно, я сделал что-то не так здесь.

Ответы [ 2 ]

0 голосов
/ 16 октября 2019

Я бы реорганизовал набор тестов следующим образом:

// ...
// 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'
  });
});
// ...
0 голосов
/ 16 октября 2019

Возвращаемое значение из 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
});

См. Документы здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...