Jak napisac test jednostkowy dla takiej funkcji

0

Witam, mam problem napisanie unit testu dla funkcji loadTime,. Funkcja ta przerabia mape (timeTable) która: wygląda tak:
https://zapodaj.net/8ed88aaa570bb.png.html
na tablice result która składa sie z (0,1) - od indexu 3-5(03:00-05:00) to są jedynki i i od 12-14(12:00-14:00) to tez są jedynki dla reszty to są 0. I wtedy teblica result jest przypisywana do tablicy rowTable. Jak ja mogę napisać do tego unit test?

rowTable wyglada tak:

  rowTable: Row[] = [
    { name: this.allDays.monday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.tuesday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.wednesday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.thursday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.friday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.saturday, items: new Array(24).fill(1), active: true },
    { name: this.allDays.sunday, items: new Array(24).fill(1), active: true }
  ];

a funkcja docelowa: loadTime

loadingTime(): void {
   if (this.inputObject?.timeTable) {
     let result = [...this.inputObject.timeTable].reduce((r, [key, value], i) => {
       r[i] = Array(24).fill(0);
       value.forEach(o => {
         let start = getHours(o.from);
         const end = getHours(o.to);
         while (start <= end) {
           r[i][start] = 1;
           start++;
         }
       })
       return r;
     }, []);
 
     this.rowTable.forEach((el, i) => {
       el.items = result[i];
       el.active = false;
     })
   }
 }

Kombinowalem jakos tak:

it("should loading Time"), () => {
 
  const timetableMock = new Map<number, Array<HourScheduleDefinitionModel>>()
      timetableMock.set(0, [{ from: '00:00', to: '23:00' }]);
 
  component.loadingTime = () => {};
 
  const onSaveSpy = spyOn(component, "loadingTime")
 
  component.loadingTime();
 
  expect(onSaveSpy).toEqual([........]);
 
}

Ale mam wrażenie, ze robie to bez sensu. Prosze o pomoc

3

Przerób tę funkcję na coś takiego:

y = f(x)

następnie Twoje testy powinny sprawdzić kilka przypadków w stylu:

assert y1 == f(x1)
assert y2 == f(x2)

Jeżeli f(...) jest niedeterministyczne, tj. np. zależy od funkcji czasu to najlepiej spróbować wstrzyknąć tę funkcję czasu jako dodatkowy argument i ją zamockować tak, żeby jednak ta funkcja była deterministyczna, tj.

assert y1 == f(x1, timerFun)

gdzie timerFun będzie np. zwracało zawsze tę samą datę.

0

Probowałem jednak cos tam pisać, ale mam błąd, że: TypeError: Cannot set properties of undefined (setting 'timeTable'). Wiesz o co chodzi?

it('loadingTime should not update rowTable if timeTable is undefined', () => {
  const rowTableForEachSpy = jest.spyOn(component.rowTable, 'forEach');
  component.timeTable = void 0;
  component.loadingTime();
  expect(rowTableForEachSpy).not.toHaveBeenCalled();
})

it('loadingTime should update rowTable if timeTable is defined', () => {
  const rowTableForEachSpy = jest.spyOn(component.rowTable, 'forEach');
  component.timeTable =  new Map().set(0,[{from:"00:00", to:"23:00"];
  component.loadingTime();
  expect(rowTableForEachSpy).toHaveBeenCalled();
})
1
dcielak napisał(a):

Probowałem jednak cos tam pisać, ale mam błąd, że: TypeError: Cannot set properties of undefined (setting 'timeTable'). Wiesz o co chodzi?

it('loadingTime should not update rowTable if timeTable is undefined', () => {
  const rowTableForEachSpy = jest.spyOn(component.rowTable, 'forEach');
  component.timeTable = void 0;
  component.loadingTime();
  expect(rowTableForEachSpy).not.toHaveBeenCalled();
})

it('loadingTime should update rowTable if timeTable is defined', () => {
  const rowTableForEachSpy = jest.spyOn(component.rowTable, 'forEach');
  component.timeTable =  new Map().set(0,[{from:"00:00", to:"23:00"];
  component.loadingTime();
  expect(rowTableForEachSpy).toHaveBeenCalled();
})

Nie można ustawić wartości timeTable, pewnie z tym zapisem ma problem component.timeTable = void 0

Ogólnie co do kodu to próbujesz sprawdzić, czy metoda używa pętli forEach na tablicy
jest.spyOn(component.rowTable, 'forEach'); co według mnie jest kompletnie bez sensu. Jakikolwiek refaktor tej pętli na coś innego for of, for in, reduce itd będzie powodował także zmianę testów pomimo tego, że metoda tworzy ten sam rezultat.

Powinieneś to uprościć tak jak zasugerował @twoj_stary_pijany, albo sprawdzić, czy zmienił się stan komponentu po wywołaniu metody.

1

@dcielak:

Funkcja ta przerabia mape (timeTable) która: wygląda tak:
https://zapodaj.net/8ed88aaa570bb.png.html
na tablice result która składa sie z (0,1) - od indexu 3-5(03:00-05:00) to są jedynki i i od 12-14(12:00-14:00) to tez są jedynki

Test polega na tym, że sprawdzasz to co robi ta funkcja. Czyli np. wrzucasz ziemniaka do pudełka i na wyjściu otrzymujesz obranego ziemniaka i sprawdzasz czy ziemniak jest obrany?

Tak samo tutaj. Na wejściu wrzucasz mapę a na wyjściu otrzymujesz tablicę, która przyjmuje pewne wartości. Wystarczy że przygotujesz sobie mapę dla której masz wynik i porównasz ten wynik z tablicą która wypluje funkcja.

1 użytkowników online, w tym zalogowanych: 0, gości: 1