我与同事讨论了单元测试问题。 我们假设我们对NSDate有一个扩展,如下所示:
func age() -> Int {
let calendar = NSDate().currentCalendar()
let yearComponent = calendar.components(.Year, fromDate: self, toDate: toDate, options: [])
return yearComponent.year
}
我测试它的方法是创建参考函数:
func ageReference(date: NSDate) -> Int {
let calendar = NSCalendar.currentCalendar()
let yearComponent = calendar.components(.Year, fromDate: date, toDate: NSDate(), options: [])
return yearComponent.year
}
...
func testAgeCalculation() {
let components = NSDateComponents()
for year in 1920.stride(to: 2016, by: 14) {
components.year = year
for month in 1...12 {
components.month = month
for day in 1.stride(to: 28, by: 4) {
components.day = day
let date = NSDate.dateWithComponents(components)
XCTAssertEqual(date.age(), ageReference(date))
}
}
}
}
我的同事和我争辩说我用f(x)测试f(x),因为ageReference()
和age()
完全相同。他们说我不能确定我的参考功能是否正确所以测试无效。对于他们来说,静态情况如下更好:
func testAgeCalculation() {
let components = NSDateComponents()
components.day = 10
components.month = 2
components.year = 1990
var date = NSCalendar.currentCalendar().dateFromComponents(components)
XCTAssertEqual(date?.age(toDate), 0)
....
}
但是检查引用函数可以保护代码不受年龄函数的影响:
func age() -> Int {
let to = NSDate().timeIntervalSinceReferenceDate
let from = self.timeIntervalSinceReferenceDate
let age = Int((to - from) / (60*60*24*365))
return age
}
在单元测试中使用这样的参考函数是否合理,或者这是一种不好的做法,不应该不惜一切代价使用它?