【问题标题】:What's a good approach to unit test an NSDateFormatter? [duplicate]对 NSDateFormatter 进行单元测试的好方法是什么? [复制]
【发布时间】:2016-06-11 19:58:22
【问题描述】:

我有一个日期数组,我想使用 NSDateFormatter 从中获取 NSDate 对象。

let dates = [
    "Tue, 04 Feb 2014 22:03:45 Z",
    "Sun, 05 Jun 2016 08:35:14 Z",
    "Sun, 05 Jun 2016 08:54 +0000",
    "Mon, 21 Mar 2016 13:31:23 GMT",
    "Sat, 04 Jun 2016 16:26:37 EDT",
    "Sat, 04 Jun 2016 11:55:28 PDT",
    "Sun, 5 Jun 2016 01:51:07 -0700",
    "Sun, 5 Jun 2016 01:30:30 -0700",
    "Thu, 02 June 2016 14:43:37 GMT",
    "Sun, 5 Jun 2016 01:49:56 -0700",
    "Fri, 27 May 2016 14:32:19 -0400",
    "Sun, 05 Jun 2016 01:45:00 -0700",
    "Sun, 05 Jun 2016 08:32:03 +0000",
    "Sat, 04 Jun 2016 22:33:02 +0000",
    "Sun, 05 Jun 2016 01:52:30 -0700",
    "Thu, 02 Jun 2016 15:24:37 +0000"
]

我一直在使用 GWT 模式,但我觉得像这样构建我的单元测试很奇怪,因为我需要为每个案例编写十几个或更多不同的测试函数。

任何人都可以提出更好的方法吗?或者这是“给定,何时,然后”模式的可接受用法?

..我真的不想有 testRFC822DateFormatter1(), testRFC822DateFormatter2(), testRFC822DateFormatter3(),...

func testRFC822DateFormatter() {

    // Given
    let rfc822DateFormatter = RFC822DateFormatter()
    let dateString = "Tue, 04 Feb 2014 22:03:45 Z"

    // When
    let date = rfc822DateFormatter.dateFromString(dateString)

    // Then
    XCTAssertNotNil(date)

    let components = NSCalendar.currentCalendar().components([.Year, .Month, .Day, .Hour, .Minute, .Second, .TimeZone, .Calendar], fromDate: date!)

    XCTAssertEqual(components.day, 4)
    XCTAssertEqual(components.month, 2)
    XCTAssertEqual(components.year, 2014)
    XCTAssertEqual(components.hour, 22)
    XCTAssertEqual(components.minute, 3)
    XCTAssertEqual(components.second, 45)
    XCTAssertEqual(components.timeZone?.daylightSavingTimeOffset, 3600)
    XCTAssertEqual(components.timeZone?.secondsFromGMT, 3600)
    XCTAssertEqual(components.calendar?.calendarIdentifier, NSCalendarIdentifierGregorian)

}

谢谢!

【问题讨论】:

  • 我很好奇你为什么要编写自己的日期格式化程序而不是只使用NSDateFormatter
  • 我是,它实际上是 NSDateFormatter 的子类。我事先不知道格式可能是什么,只知道它符合 3 个可能的 RFC 规范中的 1 个,不幸的是,它需要与上面的一个(RFC822)松散。
  • 我假设字符串数组只是一个代表性样本? (否则,您可以只创建一个 NSDates 数组并完成它。)
  • 我还不能称之为代表。我将与 700 多个不同的日期源集成。我需要测试它如何根据规范中的几种不同日期格式来解释字符串日期。就像我说的,不幸的是,我还需要在规范上松散一些。仅从 stringFromDate 方法获取 NSDate 对象并不能保证我正确理解了日期。
  • 无论如何,我才刚刚开始进行单元测试。还没有多少经验,也许写很多类似的函数其实是一个完全没问题的方法……

标签: swift unit-testing xctest


【解决方案1】:

您需要进行两种测试。

1) 确保特定日期格式与特定日期格式正常工作的测试。 2) 一项测试,以确保如果两个不同的 dateFormats 对特定的日期格式起作用,它们要么相同,要么你的逻辑会选择正确的。

因此,我设想为每个 dateFormat 进行一项测试,并为可能匹配多种格式的每个日期进行一项测试。

据我所知,对于这些测试,GWT 模式很好。更重要的是确定您需要使用的所有各种日期格式,并确保每个日期都使用正确的日期格式。


顺便说一句,我不愿意继承 NSDateFormatter,我也不认为它是必要的......对于您在问题中指定的输入,下面的代码就是所有必要的:

let dateFormatter1: NSDateFormatter = {
    let result = NSDateFormatter()
    result.dateFormat = "EEE, d MMM yyyy HH:mm:ss Z"
    return result
}()

let dateFormatter2: NSDateFormatter = {
    let result = NSDateFormatter()
    result.dateFormat = "EEE, d MMM yyyy HH:mm Z"
    return result
}()

let dateFormatter3: NSDateFormatter = {
    let result = NSDateFormatter()
    result.dateFormat = "EEE, d MMM yyyy HH:mm:ss z"
    return result
}()

func dateFromString(dateString: String) -> NSDate? {
    return dateFormatter1.dateFromString(dateString) ?? dateFormatter2.dateFromString(dateString) ?? dateFormatter3.dateFromString(dateString)
}

对于上面的代码,我希望总共进行三个测试,每个日期格式化程序一个。

【讨论】:

  • 我会在测试部分听从你的建议。顺便说一句,当你说你“不愿意继承 NSDateFormatter”时,我觉得你给了我一个曲线球。我的意思是,这是哎呀。你为什么不这样做的任何具体原因?我正在使用 3 种不同的规格,这些规格大约有十几种或更多可能的格式。不管怎样,谢谢楼主。感谢您的帮助。
  • 几个不同的原因... (1) NSDateFormatter 不是为子类而设计的。 (2) 我希望您的代码中没有任何地方可以接受 NSDateFormatter 作为参数/属性,您甚至可以在其中插入日期格式化程序(因为这是您应该子类化的唯一原因,所以不需要子类化。 ) 更好的办法是为每个日期来源使用一个特定的日期格式化程序,并在日期来自该来源时仅使用该日期格式化程序。这避免了尝试使一个日期格式化程序“全部格式化”的整个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 2010-09-07
  • 1970-01-01
相关资源
最近更新 更多