Tutorial: Firebase Mock Basics
When writing unit tests with Firebase Mock, you’ll typically want to focus on covering one of two scenarios:
- Your client receives data from Firestore using a method like
get
- Your client writes data to Firestore using a method like
set
,create
orupdate
While your application almost certainly does both reading and writing to Firestore, each test should try to cover as small a unit of functionality as possible.
Testing Reads
In this example, our source code will listen for new people on a reference we provide and call a function each time a new one is added.
Source
var collection;
var people = {
collection: function () {
if (!collection) collection = firebase.firestore().collection('people');
return collection;
},
greet: function (person) {
console.log('hi ' + person.first);
},
process: function () {
people.collection().get().then(function(snaps) {
snaps.forEach(function(doc) {
people.greet(doc.data());
});
});
}
};
In our tests, we’ll override the greet
method to verify that it’s being called properly.
Test
MockFirebase.override();
var greeted = [];
people.greet = function (person) {
greeted.push(person);
};
people.collection().add({
first: 'Michael'
});
people.collection().add({
first: 'Ben'
});
people.process();
people.collection().flush();
console.assert(greeted.length === 2, '2 people greeted');
console.assert(greeted[0].first === 'Michael', 'Michael greeted');
console.assert(greeted[1].first === 'Ben', 'Ben greeted');
We’re calling MockFirebase.override
to replace the real Firebase
instance with Firebase Mock. If you’re loading Firebase using Node or Browserify, you need to use proxyquire instead.
Notice that we queued up multiple changes before actually calling ref.flush
. Firebase Mock stores these changes in the order they were created and then performs local updates accordingly. You’ll only need to flush
your changes when you need listeners, callbacks, and other asynchronous responses to be triggered.
Testing Writes
Testing writes is especially easy with Firebase Mock because it allows you to inspect the state of your data at any time. In this example, we’ll add a new method to people
that creates a new person with the given name:
Source
people.create = function (first) {
return people.collection().add({
first: first
});
};
Test
var newPersonRef = people.create('James');
newPersonRef.then(function(doc) {
console.assert(doc.get('first') === 'James', 'James was created');
});
people.collection().flush();