2016-12-14 29 views
12

Jestem nowy w pisaniu testów jednostkowych i potrzebuję pomocy w testowaniu części funkcji.Test jednostkowy z moment.js

Moja funkcja wygląda tak ...

getData() { 
return this.parameters.map(p => { 
     return { 
      name: p.name, 
      items: p.items.map(item => { 

       const toTime = item.hasOwnProperty('end') ? moment.utc(item.end._d).unix() : null; 
       const fromTime = item.hasOwnProperty('start') ? moment.utc(item.start._d).unix() : null; 

       return { 
        id: item.id, 
        fromTime: fromTime, 
        toTime: toTime, 
       }; 
      }), 
     }; 
    }); 
} 

i do tej pory mój testowy wygląda następująco (jaśmin)

describe('getData()', function() { 
it('should return json data', function() { 
    $ctrl.parameters = [{ 
     name: 'test', 
     items: [{ 
      id: 1, 
      fromTime: null, 
      toTime: null 
     }, { 
      id: 13, 
      fromTime: null, 
      toTime: null 

     }] 
    }]; 

    expect($ctrl.getData()).toEqual([{ 
     name: 'test', 
     items: [{ 
      id: 1, 
      fromTime: null, 
      toTime: null 
     }, { 
      id: 13, 
      fromTime: null, 
      toTime: null 
     }] 
    }]); 
}); 
}); 

ten test działa/mijania, ale jak widać mam nie testuję potrójnego, jeśli/else używa Moment.js. Zasadniczo to, co robi trójskładnik, polega na sprawdzeniu, czy elementy zawierają właściwość o nazwie start/end, a jeśli tak, skonwertuj tę wartość na znacznik czasu epoki/unix i przypisz ją do toTime lub fromTime. Jeśli więc elementy mają właściwość o nazwie koniec z wartością 'Sat Oct 31 2015 00:00:00 GMT+0000 (GMT)', to zostanie ona przekształcona na '1446249600' i przypisana do toTime

Mam nadzieję, że to wyjaśnia! Nie jestem pewien, jak napisać test na ten temat i byłbym wdzięczny za każdą pomoc/sugestie.

Odpowiedz

6

Najprostszą opcją jest po prostu skonstruować kilka przykładowych dat ręcznie dla danych wejściowych. Na przykład:

$ctrl.parameters = [{ 
    name: 'test', 
    items: [{ 
     id: 1, 
     start: moment.utc('2017-01-01T01:00:00'), 
     end: moment.utc('2017-01-01T06:00:00') 
    }, { 
     id: 13, 
     start: moment.utc('2017-01-02T08:00:00'), 
     end: null 

    }] 
}]; 

(Uwaga: W powyższym przykładzie, zmieniłem fromTime i toTime do start i end, odpowiednio, ponieważ to właśnie getData oczekuje na wejściu).

następnie dowiedzieć się ich UNIX znaczniki czasu. Można zrobić tę część na zewnątrz - na przykład, po prostu otworzył narzędzi programistycznych przeglądarka (F12) na moment.js stronie oceniano następujące instrukcje w konsoli i chwycił wartości datownika:

moment.utc('2017-01-01T01:00:00').unix() 
moment.utc('2017-01-01T06:00:00').unix() 
moment.utc('2017-01-02T08:00:00').unix() 

Wreszcie z powrotem w badanej jednostki, po prostu sprawdzić, czy znaczniki czasu dopasować oczekiwanych wartości:

expect($ctrl.getData()).toEqual([{ 
    name: 'test', 
    items: [{ 
    id: 1, 
    fromTime: 1483232400, 
    toTime: 1483250400 
    }, { 
    id: 13, 
    fromTime: 1483344000, 
    toTime: null 
    }] 
}]); 

Ewentualnie, jeśli wolisz nie szuają znaczników czasu w badaniach jednostkowych, można zamiast przechowywać każdą datę przykład we własnej zmiennej (np. start1, end1), a następnie porównaj z np. start1.unix():

// Arrange 
const start1 = moment.utc('2017-01-01T01:00:00'); 
const end1 = moment.utc('2017-01-01T06:00:00'); 
const start2 = moment.utc('2017-01-02T08:00:00'); 
$ctrl.parameters = [{ 
    name: 'test', 
    items: [{ 
     id: 1, 
     start: start1, 
     end: end1 
    }, { 
     id: 13, 
     start: start2, 
     end: null 

    }] 
}]; 

// Act 
const result = $ctrl.getData(); 

// Assert 
expect(result).toEqual([{ 
    name: 'test', 
    items: [{ 
    id: 1, 
    fromTime: start1.unix(), 
    toTime: end1.unix() 
    }, { 
    id: 13, 
    fromTime: start2.unix(), 
    toTime: null 
    }] 
}]); 

To perfekcyjnie, ponieważ test jednostka jest przeznaczona do testowania kodu, a nie moment.js. To zależy od Ciebie.

Należy również pamiętać, że używam wzoru Arrange-Act-Assert do organizacji testu. Znowu do ciebie, ale gdy twoje testy jednostek zaczynają się komplikować, to sprawia, że ​​łatwiej jest podążać.

Tak czy inaczej, trzeba będzie zmienić sposób obliczania toTime i fromTime w swojej metodzie getData, ponieważ kod jako pisemnej nie będzie działać, jeśli przechodzą w null dla obu start lub end. W szczególności, item.hasOwnProperty('start') zwróci wartość true, jeśli przekażemy wartość null dla start, ale wystąpi błąd, ponieważ próbuje oszacować wartość item.start._d. Zamiast tego zalecamy zmianę tych 2 linii do następujących:

const toTime = item.end ? moment.utc(item.end._d).unix() : null; 
const fromTime = item.start ? moment.utc(item.start._d).unix() : null; 

Chciałbym również odradzam pomocą właściwości obiektu chwili _d, ponieważ jest to wewnętrzna zmienna (prywatny). Od start i end są już obiekty chwilę, może zamiast być w stanie po prostu to zrobić:

const toTime = item.end ? item.end.unix() : null; 
const fromTime = item.start ? item.start.unix() : null; 

Kompletny jsbin przykład zawierające wszystkie powyższe zaleca zmian dostępna jest tutaj:

https://jsbin.com/xuruwuzive/edit?js,output

Zauważ, że niektóre poprawki musiały zostać wprowadzone, aby działały poza kontekstem AngularJS (sprawiają, że getData jest samodzielną funkcją, która akceptuje jej parametry bezpośrednio, a nie przez $ctrl).

+0

Dziękujemy! To działa. I dzięki za próbkę! –