【发布时间】:2017-04-10 01:23:00
【问题描述】:
我正在尝试验证我存储的两个项目是否相同。但是,在测试时检查 Date 属性时出现错误。
注意:我的 Item 类实现了Equatable 协议。
这是我的设置方法:
class InputViewControllerTests: XCTestCase {
var sut: InputViewController!
var placemark: MockPlacemark!
override func setUp() {
super.setUp()
let storyboard = UIStoryboard(name: "Main",
bundle: nil)
sut = storyboard
.instantiateViewController(
withIdentifier: "InputViewController")
as! InputViewController
_ = sut.view
}
}
这是我的测试类的扩展:
extension InputViewControllerTests {
class MockGeocoder: CLGeocoder {
var completionHandler: CLGeocodeCompletionHandler?
override func geocodeAddressString(
_ addressString: String,
completionHandler: @escaping CLGeocodeCompletionHandler) {
self.completionHandler = completionHandler
}
}
class MockPlacemark : CLPlacemark {
var mockCoordinate: CLLocationCoordinate2D?
override var location: CLLocation? {
guard let coordinate = mockCoordinate else
{ return CLLocation() }
return CLLocation(latitude: coordinate.latitude,
longitude: coordinate.longitude)
}
}
}
这是我的测试:
func test_Save_UsesGeocoderToGetCoordinateFromAddress() {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let timestamp = 1456095600.0
let date = Date(timeIntervalSince1970: timestamp)
sut.titleTextField.text = "Foo"
sut.dateTextField.text = dateFormatter.string(from: date)
sut.locationTextField.text = "Bar"
sut.addressTextField.text = "Infinite Loop 1, Cupertino"
sut.descriptionTextField.text = "Baz"
let mockGeocoder = MockGeocoder()
sut.geocoder = mockGeocoder
sut.itemManager = ItemManager()
sut.save()
placemark = MockPlacemark()
let coordinate = CLLocationCoordinate2DMake(37.3316851,
-122.0300674)
placemark.mockCoordinate = coordinate
mockGeocoder.completionHandler?([placemark], nil)
let item = sut.itemManager?.item(at: 0)
let testItem = ToDoItem(title: "Foo",
itemDescription: "Baz",
timestamp: timestamp,
location: Location(name: "Bar",
coordinate: coordinate))
XCTAssertEqual(item, testItem)
}
这是save()方法的实现:
class InputViewController: UIViewController {
// ...
@IBAction func save() {
guard let titleString = titleTextField.text,
titleString.characters.count > 0 else { return }
let date: Date?
if let dateText = self.dateTextField.text,
dateText.characters.count > 0 {
date = dateFormatter.date(from: dateText)
} else {
date = nil
}
let descriptionString = descriptionTextField.text
if let locationName = locationTextField.text,
locationName.characters.count > 0 {
if let address = addressTextField.text,
address.characters.count > 0 {
geocoder.geocodeAddressString(address) {
[unowned self] (placeMarks, error) -> Void in
let placeMark = placeMarks?.first
let item = ToDoItem(
title: titleString,
itemDescription: descriptionString,
timestamp: date?.timeIntervalSince1970,
location: Location(
name: locationName,
coordinate: placeMark?.location?.coordinate))
self.itemManager?.add(item)
}
}
}
}
}
我无法弄清楚这有什么问题。我得到的错误是:
test_Save_UsesGeocoderToGetCoordinateFromAddress()] 失败:XCTAssertEqual 失败:("Optional(ToDo.ToDoItem(title: "Foo", itemDescription: Optional("Baz"), timestamp: Optional(1456030800.0)), location: Optional(ToDo.Location(名称:“酒吧”,坐标:可选(__C.CLLocationCoordinate2D(纬度:37.331685100000001,经度:-122.03006739999999))))))”)不等于(“可选(ToDo.ToDoItem(标题:“Foo”,itemDescription:可选(“Baz”),时间戳:可选(1456095600.0),位置:可选(ToDo.Location(名称:“Bar”,坐标:可选(__C.CLLocationCoordinate2D(纬度:37.331685100000001,经度:-122.03006739999999)))))) ") -
可以清楚地看到,问题是两者的时间戳不一样,我不知道它为什么会改变。
编辑:正如@ganzogo 发现的那样,这两个项目之间也有正好 18 小时的差异。我住在厄瓜多尔,这是 GTM-5。也许这可能是找出问题的线索。
【问题讨论】:
-
使用
XCTAssertEqual,您可以检查对象地址的相等性。但是你的item和testItem不一样。 -
@ArtemNovichkov,请注意,正如我所说,一切都是一样的,但
tiemestamp属性,我不知道为什么,因为我使用1456095600.0来创建两者。实际上,请注意item是 1456030800.0,而testItem是 1456095600.0。我不知道为什么 item 的值会发生变化。 -
顺便说一句@ArtemNovichkov,我认为只要一个类实现了
Equatable协议,你就可以检查相等性,而我的Item 类可以。 -
时差正好是 18 小时,所以我怀疑是时区问题。
-
您首先需要确定
testItem或item显示的时间是否正确,然后您需要通过手动穿越时区来调整另一个。单元测试将在模拟器或设备上运行,DateFormatter等类将默认使用设备的时区,因此您需要覆盖它。
标签: ios swift unit-testing testing xctest