2016-12-14 402 views
12

我是編寫單元測試的新手,需要一些幫助測試函數的一部分。使用moment.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 
     }] 
    }]); 
}); 
}); 

此測試工作/傳球,但你可以看到我我沒有測試使用Moment.js的三元if/else。基本上,三元組的功能是檢查項目是否包含名爲start/end的屬性,如果有,請將該值轉換爲epoch/unix時間戳,並將其分配給toTimefromTime。所以如果物品有一個叫做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 

    }] 
}]; 

(請注意,在上面的例子中,我改變fromTimetoTime分別startend,因爲這是getData期待的輸入。)

然後找出自己的UNIX時間戳。你可以做外部這部分 - 例如,我只是moment.js網站上開闢了瀏覽器的開發者工具(F12),評估在控制檯下面的語句,並搶下時間戳值:

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),然後與例如比較10:

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

這很好,因爲單元測試是爲了測試你的代碼,而不是moment.js。隨你便。

請注意,我正在使用Arrange-Act-Assert模式來組織測試。再次,由你決定,但是一旦你的單元測試開始變得複雜,這往往會讓事情更容易遵循。

無論哪種方式,您需要更改您如何在getData方法計算toTimefromTime,因爲書面如果你null通過對兩種startend將無法​​正常工作的代碼。特別是,item.hasOwnProperty('start')將返回true,如果您通過startnull值,但它會錯誤,因爲它會嘗試評估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,因爲這是一個內部(私有)變量。由於startend已經瞬間的對象,你可以改爲能夠只是做到這一點:

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的上下文之外運行(使getData成爲直接接受其參數的獨立函數,而不是通過$ctrl)。

+0

謝謝!它的工作。也謝謝你的樣品! –