gpt4 book ai didi

reactjs - 如何模拟 Firebase Auth 方法? ( react ,测试库)

转载 作者:行者123 更新时间:2023-12-05 03:57:23 25 4
gpt4 key购买 nike

我有以下组件:

import React from "react";
import Firebase from "../../Firebase";

const SignOutButton = () => (
<button type="button" onClick={() => Firebase.auth().signOut()}>
Sign Out
</button>
);

export default SignOutButton;

我想测试 Firebase.auth().signOut 是否调用了 onClick

我在其他地方找到了 Firebase.auth 的模拟:

const authMock = jest.fn(() => {
return {
createUserAndRetrieveDataWithEmailAndPassword: jest.fn(() =>
Promise.resolve(true)
),
sendPasswordResetEmail: jest.fn(() => Promise.resolve(true)),
signInAndRetrieveDataWithEmailAndPassword: jest.fn(() =>
Promise.resolve(true)
),
fetchSignInMethodsForEmail: jest.fn(() => Promise.resolve(true)),
signOut: jest.fn(() => {
Promise.resolve(true);
}),
onAuthStateChanged: jest.fn(),
currentUser: {
sendEmailVerification: jest.fn(() => Promise.resolve(true))
}
};
});

export { authMock };

在 SignOutButton.test 中我有:

import React from "react";
import { render, cleanup, fireEvent } from "@testing-library/react";
import SignOutButton from "../.";
import Firebase from "../../../Firebase";
import { authMock } from "../../../../setupTests";
// @ts-ignore
Firebase.auth = authMock;

describe("<SignOutButton />", () => {
afterEach(cleanup);

it("calls Firebase signOut on click", async () => {
const { getByText } = render(<SignOutButton />);
const button = getByText("Sign Out");

fireEvent.click(button);

expect(Firebase.auth().signOut).toHaveBeenCalled();
});
});

我的测试结果是预期调用为 1 但接收到 0。

我做错了什么?

谢谢!

最佳答案

您的测试存在以下问题:

  1. 在将 Firebase.auth 方法替换为 authMock 之后,您应该导入 SignOutButton 组件。否则,Firebase.auth 方法是原始版本而不是模拟版本。您可以使用 console.log(Firebase.auth) 进行检查。

  2. 您应该为 Firebase.auth 方法的返回值返回相同的引用。否则,断言将失败。

完整的单元测试解决方案:

SignOutButton.tsx:

import React from 'react';
import Firebase from './firebase';

console.log(Firebase.auth);
console.log('should keep same reference to authObject:', Firebase.auth() === Firebase.auth());

const SignOutButton = () => (
<button type="button" onClick={() => Firebase.auth().signOut()}>
Sign Out
</button>
);

export default SignOutButton;

firebase.ts:

export default {
auth() {
console.log('auth real implementation');
return this;
},
async signOut() {
console.log('signOut real implementation');
},
};

setupTests.ts:

const authObjectMock = {
createUserAndRetrieveDataWithEmailAndPassword: jest.fn(() => Promise.resolve(true)),
sendPasswordResetEmail: jest.fn(() => Promise.resolve(true)),
signInAndRetrieveDataWithEmailAndPassword: jest.fn(() => Promise.resolve(true)),
fetchSignInMethodsForEmail: jest.fn(() => Promise.resolve(true)),
signOut: jest.fn(() => {
Promise.resolve(true);
}),
onAuthStateChanged: jest.fn(),
currentUser: {
sendEmailVerification: jest.fn(() => Promise.resolve(true)),
},
};
const authMock = jest.fn(() => authObjectMock);

export { authMock };

SignOutButton.test.tsx:

import React from 'react';
import { render, cleanup, fireEvent } from '@testing-library/react';
import Firebase from './firebase';
import { authMock } from './setupTests';
// @ts-ignore
Firebase.auth = authMock;

describe('<SignOutButton />', () => {
afterEach(cleanup);

it('calls Firebase signOut on click', async () => {
const SignOutButton = (await import('./SignOutButton')).default;
const { getByText } = render(<SignOutButton />);
const button = getByText('Sign Out');
fireEvent.click(button);
expect(Firebase.auth().signOut).toHaveBeenCalled();
});
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/58562583/SignOutButton.test.tsx
<SignOutButton />
✓ calls Firebase signOut on click (76ms)

console.log src/stackoverflow/58562583/SignOutButton.tsx:382
{ [Function: mockConstructor]
_isMockFunction: true,
getMockImplementation: [Function],
mock: [Getter/Setter],
mockClear: [Function],
mockReset: [Function],
mockRestore: [Function],
mockReturnValueOnce: [Function],
mockResolvedValueOnce: [Function],
mockRejectedValueOnce: [Function],
mockReturnValue: [Function],
mockResolvedValue: [Function],
mockRejectedValue: [Function],
mockImplementationOnce: [Function],
mockImplementation: [Function],
mockReturnThis: [Function],
mockName: [Function],
getMockName: [Function] }

console.log src/stackoverflow/58562583/SignOutButton.tsx:386
should keep same reference to authObject: true

-------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files | 63.64 | 100 | 36.36 | 60 | |
SignOutButton.tsx | 100 | 100 | 100 | 100 | |
firebase.ts | 25 | 100 | 0 | 25 | 3,4,7 |
setupTests.ts | 50 | 100 | 28.57 | 44.44 | 2,3,4,5,11 |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.943s

关于reactjs - 如何模拟 Firebase Auth 方法? ( react ,测试库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58562583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com