Reputation: 101
I'm trying to write some unit tests for some model objects I'm developing. I'm seeing some strange unexpected behavior when getting Timestamps out of an dictionary [String:Any]. The timestamp is nil when trying to cast to a non-optional. But you can see in the print outputs that it's a timestamp. Does anyone have any ideas?
The output of the two print statements is:
nil
Optional(<FIRTimestamp: seconds=1562802592 nanoseconds=1123>)
import XCTest
import Firebase
@testable import MyTarget
class UserTest: XCTestCase {
var testDict:[String : Any]? = [:]
var renewalDate:Timestamp = Timestamp(seconds: Int64(1562802592), nanoseconds: Int32(1123))
override func setUp() {
super.setUp()
testDict = [
"userId": "userId",
"firstName": "J",
"lastName" : "R",
"email": "[email protected]",
"renewalDate": renewalDate
]
}
func testInit_ReturnsInstanceWhenRequiredPropertiesAreSpecificed() {
let zUser = ZenUser(dictionary: testDict)
XCTAssertNotNil(zenUser, "ZenUser should not be nil")
}
}
ZenUser : DocumentDeserializable {
init?(dictionary:[String:Any]?) {
let t = dictionary?["renewalDate"] as? Timestamp
print(t)
print(dictionary?["renewalDate"])
guard let userId = dictionary?["userId"] as? String,
let firstName = dictionary?["firstName"] as? String,
let renewalDate = dictionary?["renewalDate"] as? Timestamp,
let lastName = dictionary?["lastName"] as? String else {
print("Missing fields, returning nil")
return nil
}
...
}
protocol DocumentDeserializable {
init?(dictionary: [String: Any]?)
}
Why is the timestamp nil when casting to non-optional?
Here are the versions I'm using.
Using Firebase (6.4.0)
Using FirebaseABTesting (3.0.0)
Using FirebaseAnalytics (6.0.3)
Using FirebaseAuth (6.2.0)
Using FirebaseAuthInterop (1.0.0)
Using FirebaseCore (6.0.4)
Using FirebaseFirestore (1.4.1)
Upvotes: 4
Views: 890
Reputation: 3157
Workaround: Create the Timestamp
in your app code rather than the test code. I needed a Timestamp
from a Date
, so I created this extension (in the app code) and use it in my tests.
Date
extension (Date+Timestamp.swift
):
import FirebaseFirestore
extension Date {
var timestamp: Timestamp {
Timestamp(date: self)
}
// add more extensions upon need
}
Add the Date
extension to your app target(s), not to the test target.
Part of the test:
let data: [String: Any] = [
Receipt.Keys.date.rawValue: Date().timestamp
]
This way the tested code can properly cast the object to a Timestamp
.
Upvotes: 1