2016-12-14 11 views
12

Я новичок в написании модульных тестов и нуждаюсь в некоторой помощи, проверяющей часть функции.Ед. Изм. С момента. Js

Моя функция выглядит следующим образом ...

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, 
       }; 
      }), 
     }; 
    }); 
} 

и до сих пор мой тест выглядит следующим образом (жасмин)

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 
     }] 
    }]); 
}); 
}); 

Этот тест работает/мимоходом, но, как вы можете видеть, я Я не тестирую троичный if/else, который использует Moment.js. В основном то, что делает trernary, проверяет, содержит ли элементы свойство start/end, и если это так, преобразуйте это значение в временную метку эпохи/unix и назначьте его либо toTime, либо fromTime. Поэтому, если элементы имеют свойство, называемое end с значением 'Sat Oct 31 2015 00:00:00 GMT+0000 (GMT)', тогда оно будет преобразовано в '1446249600' и присвоено toTime

Надеюсь, это объяснит это! Я не уверен, как написать тест для него и буду признателен за любую помощь/предложения.

ответ

6

Самый простой вариант - просто создать пару дат примера вручную для ввода. Например:

$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 

    }] 
}]; 

(примечание в приведенном выше примере, я изменил fromTime и toTime к start и end, соответственно, так это то, что getData ожидает на входе.)

Затем выяснить их UNIX метки времени. Вы можете сделать эту часть извне - к примеру, я просто открыл инструменты разработчика браузера (F12) на moment.js сайта, оценивал следующие инструкции в консоли, и схватился значение временной метки:

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

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

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

в качестве альтернативы, если вы предпочитаете не иметь жестко закодированные метки времени в модульных тестов, вы можете вместо этого хранить каждый пример даты в своей собственной переменной (например, start1, end1), а затем сравнить с, например, 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 
    }] 
}]); 

Это прекрасно, поскольку модульный тест предназначен для проверки вашего кода, а не момента .js. Тебе решать.

Обратите внимание, что я использую шаблон Arrange-Act-Assert для организации теста. Опять же, до вас, но как только ваши юнит-тесты начинают усложняться, это имеет тенденцию держать вещи легче следовать.

В любом случае, вам нужно будет изменить, как вы вычислить toTime и fromTime в методе getData, так как код, как написано не будет работать, если вы передадите null либо для start или end. В частности, item.hasOwnProperty('start') вернет true, если вы перейдете в null значение для start, но оно будет ошибочно, потому что оно пытается оценить item.start._d. Вместо этого я рекомендую изменения эти 2 строки следующим образом:

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

Я также советовал бы против использования _d свойство объекта момента, так как это является внутренним (частным) переменной. Поскольку start и end уже объекты момент, вы можете вместо того, чтобы иметь возможность просто сделать это:

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

Полный jsbin пример, содержащий все выше рекомендованных изменений можно ознакомиться здесь:

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

Обратите внимание, что необходимо сделать некоторые настройки, поэтому он выходит за пределы контекста AngularJS (make getData - автономная функция, которая принимает свои параметры напрямую, а не через $ctrl).

+0

Спасибо! Работает. И спасибо за образец тоже! –

Смежные вопросы