Модульное тестирование Angular Material: имитация события MatSelectChange

#angular #unit-testing #angular-material #mocking #jasmine

#angular #модульное тестирование #angular-material #имитация #jasmine

Вопрос:

Описание: Я пишу модульные тесты для следующей функции:

 updateUserStatus(event: MatSelectChange | any, reportID: number) {
    const matOption = (event.source.selected as MatOption);
    const option = matOption.value;
    this.setUserActions(reportID, option.id);
}
  

Спецификация теста

 it('should test updateUserStatus', () => {
    spyOn(component, 'updateUserStatus').and.callThrough();
    spyOn(component, 'setUserActions').and.callFake(() => {});
    component.updateUserStatus({{MOCK_EVENT_HERE}}, 123456);
    expect(component.updateUserStatus).toHaveBeenCalledTimes(1);
    expect(component.setUserActions).toHaveBeenCalledTimes(1);
});
  

Проблема: мне трудно имитировать аргумент ‘event’, который является экземпляром ‘MatSelectChange’.

Что я пробовал до сих пор?

1. Копирование значения ‘event’ из консоли браузера

Это дает мне:

Неперехваченная ошибка типа: преобразование циклической структуры в JSON.

2. Создайте новый экземпляр MatSelectChange

Конструктору ‘MatSelect’ требуется 12-13 аргументов, о боже!. Не знаю, как создать экземпляр:

 const selectChange = new MatSelectChange(new MatSelect(), 'Value');
  

Если отсутствует какая-либо другая деталь, пожалуйста, дайте мне знать, поможет ли это лучше понять ее.

Комментарии:

1. вы пробовали просто создать объект javascript с ключевыми полями, которые необходимы для вашего кода, и преобразовать его в MatSelectChange перед отправкой в функцию в вашем тесте?

2. Не следите за тем, что вы должны тестировать, и не вызывайте методы компонента напрямую. Что setUserActions на самом деле делает ? Протестируйте поведение компонента.

3. @NileshKesar Пока нет, попробую.

4. @jonrsharpe модульный тест должен быть небольшим, если у function_A есть код, вызывающий другую function_B, вам не следует тестировать код function_B внутри теста о function_A, поскольку независимо от того, что вы можете проверить, вызывается ли он.

5. @PradeepVig если вам нужен пример, дайте мне знать.

Ответ №1:

Если вы все еще застряли на этом, я бы просто отправил простой объект JavaScript.

Попробуйте:

 it('should test updateUserStatus', () => {
    spyOn(component, 'updateUserStatus').and.callThrough();
    spyOn(component, 'setUserActions').and.callFake(() => {});
    event.source.selected
    const mockMatSelectChange = {
      event: {
        source: {
         selected: {
           value: {
             id: '123', // mock ID to whatever it should be
           }
         } 
       }
      }
    };
    component.updateUserStatus(mockMatSelectedChange, 123456);
    expect(component.updateUserStatus).toHaveBeenCalledTimes(1);
    expect(component.setUserActions).toHaveBeenCalledTimes(1);
});
  

Комментарии:

1. Это помогло. Хотя я пытался запустить этот метод из действия DOM, это не удалось.