在单元测试期间,我想临时模拟特定国家的默认时区。这就是我目前所做的,通过使用全局变量。
应用代码
import Foundation
var _TIME_ZONE_FOR_UNIT_TEST: TimeZone? = nil
extension TimeZone {
static func current() -> TimeZone {
if let _TIME_ZONE_FOR_UNIT_TEST = _TIME_ZONE_FOR_UNIT_TEST {
return _TIME_ZONE_FOR_UNIT_TEST
} else {
return TimeZone.current
}
}
}
字符串
单元测试
func testToDayResolutionInCuba() throws {
let cubaTimeZone = TimeZone(identifier: "America/Havana")!
_TIME_ZONE_FOR_UNIT_TEST = cubaTimeZone
defer {
_TIME_ZONE_FOR_UNIT_TEST = nil
}
...
// ReminderUtils.toDayResolution is depending on TimeZone.current()
let timestampWithoutTime = ReminderUtils.toDayResolution(timeMillis)
型
虽然它的工作,我不喜欢这样的方式,
1.使用全局变量
if
检查的额外运行时成本
是否有更好的方法来执行特定时区的单元测试?
3条答案
按热度按时间qlfbtfca1#
模拟可以通过改变
NSTimeZone.default
来完成字符串
lstz6jyr2#
**此解决方案在iOS 17上不起作用,因为
Timezone.current
不再到达NSTimeZone.systemTimeZone
以进行搅拌。TimeZone
是NSTimeZone
的直接 Package 器,TimeZone.current
对应于NSTimeZone.systemTimeZone
。因此,你可以用任何mocking框架来mock/stub
NSTimeZone.systemTimeZone
。这将帮助你从代码库中摆脱讨厌的if
。mfpqipee3#
正如在另一个答案https://stackoverflow.com/a/68979424中提到的。
自iOS 17以来,
Timezone.current
不再到达NSTimeZone.systemTimeZone
,因此swizzingNSTimeZone
不再工作。但是有一种方法,新的
TimeZone
实现更喜欢TZ环境值。达尔文的
setenv
与1
参数,以强制覆盖,如果任何设置之前,允许在运行时这样做,例如。字符串
它本身并不工作,因为
TimeZone
内部使用缓存机制。但我们可以通过调用来欺骗无效过程:型
所有这些似乎在单元测试的情况下工作得很好:
型