Как макетировать класс TS в модульных тестах - PullRequest
0 голосов
/ 24 февраля 2020

Рассмотрим следующий фрагмент кода:

import {Calendar} from '@fullcalendar/core';

...

ngAfterViewInit() {
  this.calendar = new Calendar(this.element.nativeElement, config);
  this.calendar.render();
}

Я использую плагин fullcalendar, но он не имеет ничего общего с моим первоначальным вопросом, думаю, это может быть любая другая зависимость. Таким образом, плагин создает представление календаря. Команда fullcalendar должна проверить поведение календаря, а я отвечаю за проверку интеграции календаря. Поэтому мне нужно проверить, что календарь был инициализирован с правильной конфигурацией, поэтому я хочу опустить реальный конструктор и получить параметры. А также я не хочу создавать экземпляр календаря.

Как смоделировать Calendar класс в моих тестах?

1 Ответ

1 голос
/ 24 февраля 2020

Хорошей практикой является упаковка ваших библиотечных вызовов. Прежде всего, проще протестировать их, и если интерфейс библиотеки изменится, вам нужно всего лишь изменить код в одном месте и сохранить собственный интерфейс в остальной части кода.

Поэтому одно решение для вашей проблемы было бы обернуть создание календаря в заводской сервис, например:

@Injectable({providedIn:'root'})
export class FullcalendarFactoryService{

  public buildCalendar(element:HTMLElement,config:any){
    return new Calendar(element,config);
  }
}

В вашем компоненте вы должны внедрить заводской сервис и использовать его как:

constructor(public calenderFactory:FullcalendarFactoryService) {
}

ngAfterViewInit(): void {
    this.calendar = this.calenderFactory.buildCalendar(this.element.nativeElement,this.config);
    this.calendar.render();
}

И для тестирования, Вы можете просто смоделировать вашу фабричную функцию, как показано ниже:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        YourComponent
      ],
      providers: [{
        provide: FullcalendarFactoryService,
        useClass: class {
          buildCalendar = jasmine.createSpy('buildCalendar').and.returnValue({
            render: () => true
          });
        }
      }
      ]
    }).compileComponents();

    calendarFactory = TestBed.get(FullcalendarFactoryService);

}));

it('should call factory method with element and config', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();

    expect(calendarFactory.buildCalendar).toHaveBeenCalledWith(fixture.componentInstance.element.nativeElement, fixture.componentInstance.config);
  });

ОБНОВЛЕНИЕ:

Чтобы проверить, возвращает ли сервисная функция buildCalendar экземпляр Calendar, вы бы протестировали свой сервис как показано ниже:

import {FullcalendarFactoryService} from './fullcalendar-factory.service';
import {Calendar} from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid'

describe('calendar factory service', () => {
  let factory:FullcalendarFactoryService;

  beforeEach(() => {
    factory = new FullcalendarFactoryService();
  })

  it('should return calender instance',() => {
    expect(factory.buildCalendar(document.createElement('test'),{plugins:[dayGridPlugin]})).toEqual(jasmine.any(Calendar))
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...