2016-11-25 130 views
0

我試圖驗證我存儲的兩個項目是相同的。但是,在測試時,我在檢查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失敗:( 「可選(ToDo.ToDoItem(標題: 」富「,itemDescription:可選(」 巴茲「),時間戳:可選(1456030800.0 ),位置:可選(ToDo.Location(名稱:「Bar」,座標:可選(__ C.CLLocationCoordinate2D(緯度:37.331685100000001,經度:-122.03006739999999))))))「)不等於(」Optional(ToDo。 ToDoItem(title:「Foo」,itemDescription:可選(「Baz」),時間戳:可選(1456095600.0),位置:可選(ToDo.Location(名稱:「Bar」,座標:可選(__ C.CLLocationCoordinate2D(緯度:37.331685100000001,經度:-122.03006739999999))))))「) -

可以清楚地看到,問題在於兩者的時間戳都不一樣,我不知道它爲什麼會改變。

編輯:由於@ganzogo發現,這兩個項目之間存在18小時的差異。我住在厄瓜多爾,它是GTM-5。也許這可能是解決問題的一個提示。

+0

使用'XCTAssertEqual'可以檢查對象地址的相等性。但是你的'item'和'testItem'不一樣。 –

+0

@ArtemNovichkov,請注意,正如我所說的一切都是一樣的,但'tiemestamp'屬性,我不知道爲什麼,因爲我使用'1456095600.0'來創建兩個。其實,注意'item'是1456030800.0,而'testItem'是1456095600.0。我不知道爲什麼項目的價值正在發生變化。 – lmiguelvargasf

+0

和btw @ArtemNovichkov,我認爲只要一個類實現了「Equatable」協議,我的Item類就可以檢查相等性。 – lmiguelvargasf

回答

1

您的行之後:

let dateFormatter = DateFormatter() 

試試這個:

dateFormatter.timeZone = TimeZone(secondsFromGMT: 64800) 

如果還是不行,請嘗試:

dateFormatter.timeZone = TimeZone(secondsFromGMT: -64800) 

:-)

但你如果喲,那麼這就是擊敗單元測試的目的你只是在傳球時纔會進行黑客攻擊。您確實需要了解testItemitem是否正在展示正確的行爲,這取決於您的應用程序。

+0

我已經嘗試過,但都沒有工作。當我嘗試第一個時,仍然有六個小時的差異。我已經嘗試了6個小時,但現在我又有了18個小時的差距。 – lmiguelvargasf

+0

我甚至嘗試改變位置,但它仍然沒有解決。 – lmiguelvargasf

1

在FUNC test_Save_UsesGeocoderToGetCoordinateFromAddress() 時間戳變換sut.dateTextField.text,然後 在SUT。保存() sut.dateTextField.text 轉換爲時間戳,分鐘和秒分別爲