我的目的仅仅是测试一个功能。我无法弄清楚如何正确模拟Firebase。我尝试保留来自Jest docs的axios模拟示例。我有以下代码:
MusicService.js
import { initializeApp } from "firebase/app";
import "firebase/database";
const firebase = initializeApp({
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
projectId: "<PROJECT_ID>",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<SENDER_ID>",
});
export class MusicService {
static getAlbums() {
return firebase.database().ref("albums").once("value")
.then(snapshot => Object.values(snapshot.val()));
}
}
MusicService.test.js
import firebase from 'firebase/app';
import 'firebase/database';
import { MusicService } from './MusicService';
jest.mock('firebase/app');
jest.mock('firebase/database');
test("test", () => {
firebase.initializeApp.mockImplementation(() => {
database: jest.fn(() => {
return {
ref: jest.fn()
}
})
});
MusicService.getAlbums();
});
我尝试模拟firebase.database。
test("test", () => {
firebase.mockImplementation(() => {
return {
database: {
}
}
});
MusicService.getAlbums();
});
但是在这种情况下,我得到的错误提示:
TypeError:_app.default.mockImplementation不是函数。
我不希望给出工作示例,但是请您告诉我,我到底应该嘲笑什么?整个firebase库或我的函数开始的部分-return firebase.database()
。
答案 0 :(得分:1)
我知道了。我应该只模拟那些要测试的功能所依赖的模块。例如,我要测试getAlbums
函数。它使用从initializeApp
中的firebase/app
模块导入的MusicService.js
函数。因此,在调用initializeApp
函数时,它应返回一个包含database
函数的对象,而该对象又将返回一个具有ref
和once
函数的对象。代码:
MusicService.test.js 。
import { MusicService } from "./FirebaseService";
jest.mock("firebase/app", () => {
const data = { name: "unnamed" };
const snapshot = { val: () => data };
return {
initializeApp: jest.fn().mockReturnValue({
database: jest.fn().mockReturnValue({
ref: jest.fn().mockReturnThis(),
once: jest.fn(() => Promise.resolve(snapshot))
})
})
};
});
test("getAlbums function returns an array", async () => {
const data = await MusicService.getAlbums();
expect(data.constructor).toEqual(Array);
});
答案 1 :(得分:0)
这是我当前对firebase.js的模拟实现。 对我来说一切正常。
const firebase = jest.genMockFromModule('firebase');
firebase.initializeApp = jest.fn();
const data = { name: 'data' };
const snapshot = { val: () => data, exportVal: () => data, exists: jest.fn(() => true) };
firebase.database = jest.fn().mockReturnValue({
ref: jest.fn().mockReturnThis(),
on: jest.fn((eventType, callback) => callback(snapshot)),
update: jest.fn(() => Promise.resolve(snapshot)),
remove: jest.fn(() => Promise.resolve()),
once: jest.fn(() => Promise.resolve(snapshot)),
});
firebase.auth = jest.fn().mockReturnValue({
currentUser: true,
signOut() {
return Promise.resolve();
},
signInWithEmailAndPassword(email, password) {
return new Promise((resolve, reject) => {
if (password === 'sign' || password === 'key') {
resolve({ name: 'user' });
}
reject(Error('sign in error '));
});
},
createUserWithEmailAndPassword(email, password) {
return new Promise((resolve, reject) => {
if (password === 'create' || password === 'key') {
resolve({ name: 'createUser' });
}
reject(Error('create user error '));
});
},
});
export default firebase;