I am working out some kinks in my unit tests for a node app with a Firebase RTDB integration. I am trying to build tests for my Firebase listeners, but one is giving me fits.
For example, if I have this function:
export function my_function(callback) {
database.ref(`test`).on('child_changed', async snapshot => {
callback(snapshot);
});
};
and this test:
describe('my_function', () => {
beforeEach(() => {
databaseStub = sinon.stub(database, 'ref').returns({
on: sinon.stub()
});
});
afterEach(() => {
databaseStub.restore();
});
it("should call the callback function on 'child_changed'", () => {
const callback = sinon.spy();
const snapshot = {}; // for brevity; actual data is not needed
databaseStub().on.callsArgWith(1, snapshot);
my_function(callback);
expect(callback).to.have.been.calledWith(snapshot);
});
});
This test passes as expected. But, if I have this function:
export async function my_function(callback) {
database.ref('test').on('child_added', async snapshot => {
const snap = await database.ref('messages').once('value'); // <- here's the rub
// prints "depots: {}" as expected
console.log(`depots: ${ JSON.stringify(snap) }`);
// calling with a new object, not the one passed in as in the previous example
callback(snap);
});
}
With this test:
describe('my_function', () => {
beforeEach(() => {
databaseStub = sinon.stub(database, 'ref').returns({
on: sinon.stub(),
once: sinon.stub().returns({}),
update: sinon.stub()
});
});
afterEach(() => {
databaseStub.restore();
});
it("should call the callback function on 'child_added'", () => {
const callback = sinon.spy();
const snapshot = {}; // for brevity; actual data is not needed
const messages = {}; // for brevity; actual data is not needed
databaseStub().on.callsArgWith(1, snapshot);
my_function(callback);
expect(callback).to.have.been.calledWith(messages);
});
});
my test fails with AssertionError: expected spy to have been called with arguments {}
.
What am I missing?