javascript - 使用 Jest 模拟 Firebase onValue 函数
问题描述
我正在尝试onValue()
使用 Jest 模拟 Firebase 9.0.0 功能。主组件使用该onValue()
函数读取特征并呈现结果。
Acerca.js
:
import React, { useEffect, useState } from 'react'
import { db, onValue, ref } from './Firebase'
const Acerca = () => {
const [feature, setFeature] = useState('')
useEffect(() => {
let featureRef = ref(db, 'feature')
let unsubscribe = onValue(featureRef, snapshot => {
setFeature(snapshot.val())
})
return () => unsubscribe()
}, [])
return(
<>{feature ? <h3>{feature}</h3> : null}</>
)
}
export default Acerca
Acerca.test.js
:
import React from 'react'
import Acerca from './Acerca'
import { render } from 'react-dom'
import { act } from 'react-dom/test-utils'
import { onValue } from './Firebase'
it("Acerca -> displays title", async () => {
const data = {
feature: {
title: "New feature"
}
}
const snapshot = { val: () => data }
const firebase = { onValue }
const spy = jest.spyOn(firebase, 'onValue').mockImplementation(() => jest.fn((event, callback) => callback(snapshot)))
await act(async () => {
render(<Acerca/>, container)
})
expect(container.querySelector('h3').textContent).toBe(data.feature.title)
})
问题是没有调用模拟函数(空值而不是虚拟数据)并且测试失败:
模拟该功能的正确方法是什么onValue()
?
解决方案
Acerca.js
:
import React, { useEffect, useState } from 'react';
import { db, onValue, ref } from './Firebase';
const Acerca = () => {
const [feature, setFeature] = useState();
useEffect(() => {
let featureRef = ref(db, 'feature');
let unsubscribe = onValue(featureRef, (snapshot) => {
setFeature(snapshot.val().feature);
});
return () => unsubscribe();
}, []);
return <>{feature ? <h3>{feature.title}</h3> : null}</>;
};
export default Acerca;
Firebase.js
:
// simulate real firebase module
export function onValue(ref, callback) {
const snapshot = {
val() {
return 'real implementation';
},
};
callback(snapshot);
return function unsubscribe() {};
}
export function ref(db, name) {
return {};
}
export const db = {};
Acerca.test.js
:
import React from 'react';
import { render } from 'react-dom';
import { act } from 'react-dom/test-utils';
import { onValue } from './Firebase';
import Acerca from './Acerca';
jest.mock('./Firebase');
describe('Acerca', () => {
test('should pass', async () => {
const data = { feature: { title: 'New feature' } };
const snapshot = { val: () => data };
onValue.mockImplementation((ref, callback) => {
callback(snapshot);
return jest.fn();
});
const container = document.createElement('div');
await act(async () => {
render(<Acerca />, container);
});
expect(container.querySelector('h3').textContent).toBe(data.feature.title);
});
});
测试结果:
PASS examples/69324329/Acerca.test.js (8.029 s)
Acerca
✓ should pass (20 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 70 | 100 | 37.5 | 73.68 |
Acerca.js | 91.67 | 100 | 75 | 100 |
Firebase.js | 37.5 | 100 | 0 | 37.5 | 2-8,12
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.556 s
推荐阅读
- javascript - 在挂载的方法中调用监听器和 location.reload() 方法
- vba - 运行时错误 '1004' 方法 'Paste'_worksheet' 失败
- amazon-web-services - 将日志文件从客户端应用程序上传到 Amazon S3 是否安全?
- javascript - 我如何在用户被 discord.js v12 禁止之前向他们发送消息?
- rust - 在 Rust 中,如何用 self 制作 vec 的特征?
- android - Android:LiveData postValue() 为空
- c - 在 SMT-LIB 中表示 C 结构
- python - 根据列中值之间的差异编辑数据框样本
- sql - 如何将多个数据集中的观察频率计数放入一张表中?
- excel - Generate Multiple Matches of partial match