Pavel  Orel
Pavel Orel

Reputation: 164

How can I test Firebase DataSnapshot to model object parsing?

I'm trying to test the parsing of Firebase DataSnapshot object into model objects. Let's say I have this model:

struct Foo {
  var ref: DatabaseReference?
  var foo: String

  init?(snapshot: DataSnapshot) {
    guard 
      let snapValue = snapshot.value as? [String: Any],
      let foo = snapValue["foo"] as? String
      else { return nil }

    self.ref = nil // for testing purposes
    self.foo = foo
}

How can I get a snapshot with some dummy data? It appears that I can't make a DataSnapshot and set values by hand:

DataSnapshots are passed to the methods in listeners [...] They can't be modified and will never change.

I also don't think I can just initialize a DatabaseReference and set values by hand - it just comes out empty.

So how can I test this? I think I could probably change my model inits to init?(dictionary: [String: Any], ref: DatabaseReference), instead of just DataSnapshot, but this seems kind of hacky.

Upvotes: 2

Views: 480

Answers (1)

MoFlo
MoFlo

Reputation: 559

Currently over two hundred views, so clarifying for others. Refactor your method to pass a dictionary and then test both methods seperately.

struct Foo {
 var foo :String

 init?(snapshot: DataSnapshot) {
  guard let dictionary = snapshot.value as? [String: Any] 
  else { return nil }

  self.init(dict: dictionary)
 }

 init?(dict: [String:Any] {
  guard let foo = dict["foo"] as? String else { return nil }

  self.init(foo: foo)
 }

}

Then unit testing both methods such as:

func testInitDataSnapshot() {
    let snapshot = DataSnapshot()

    let dut = Foo(snapshot: snapshot)

    expect(dut).to(beNil())

}

func testInitDictionary() {
    let dict = ["foo" : "bar"]

    let dut = Foo(dict: dict)

    expect(dut).toNot(beNil())
    expect(dut.foo)to(equal("bar"))
}

Upvotes: 1

Related Questions