我使用Firebase身份验证,我想使用Jest和react挂钩测试-库来测试这个函数。
我有一个这样的功能:
const loginWithEmailPassword = (email: string, password: string) => {
const auth = getAuth()
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
}).catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
});
}signInWithEmailPassword()函数有一个then()和catch()块。
我用下面的代码来模拟这个函数:
const mockSignUp = jest.fn(() => {
return Promise.resolve({
user: {
uid: "fakeuid",
},
});
})
jest.mock('firebase/auth', () => ({
getAuth: () => mockGetAuth,
signInWithEmailAndPassword: () => mockSignIn,
createUserWithEmailAndPassword: () => mockSignUp
}))然后使用react-hooks-testing-library测试上面的函数,如下所示:
test('Login with Email and Password', () => {
const { result } = renderHook(() => useFirebaseAuth())
const email = 'abc@gmail.com'
const password = '123456'
// here fired my loginWithEmailPassword above
act(() => {
// the problem come from this line
result.current.loginWithEmailPassword(email, password)
})然后我的测试失败了,因为这个错误:
TypeError: (0 , _auth.signInWithEmailAndPassword)(...).then is not a function
46 |
47 | signInWithEmailAndPassword(auth, email, password)
> 48 | .then((userCredential) => {如果我删除then块,测试就通过了。但是,如果我使用调用的then()作为函数,它就会得到错误。我检查返回signInWithEmailAndPassword的Promise.resolve()的模拟是否正常,但它仍然存在错误。
我是测试领域的新手。请有人对此提出一些建议,并告诉我的测试有什么问题吗?我完全不知道
在寻找这个answer之后,我试着像这样嘲弄它
const mockSomething = jest.fn().mockImplementation(() => Promise.resolve({
user: {
uid: "fakeuid",
},
}))但仍然有同样的错误
发布于 2021-09-01 18:34:08
最后,我能够通过模拟一个函数来解决这个问题,这个函数将返回用user解决的承诺,如下所示:
jest.mock('firebase/auth', () => {
return {
getAuth: () => mockGetAuth,
// since this method from firebase return a promise, here need a promise as well
signInWithEmailAndPassword: jest.fn().mockResolvedValue({
user: {
uid: "fakeUid",
},
}),
createUserWithEmailAndPassword: jest.fn().mockResolvedValue({
user: {
uid: "fakeUid",
},
}),
}
})在signInWithEmailPassword中,我直接返回Promise,而不使用jest.fn()包装它
在测试中,我可以这样做:
import { signInWithEmailAndPassword, getAuth } from 'firebase/auth';
// here I can check that `signInWithEmailPassword is call with some value
expect(signInWithEmailAndPassword).toBeCalledWith(
getAuth(),
email,
password
);
// Here I can compare my UI to the fakeUid as well
expect(data.user.uid).toEqual('fakeUid')在测试中,我必须调用signInWithEmailAndPassword,这是直接从firebase/auth。
因为我已经在jest.mock()中模拟了这个函数,所以在测试中它将返回我直接定义的假数据,即data: { user: { uid: 'fakeUid' } }。
整个过程就像:
在signInWithEmailPassword
jest.mock()test部分中的相同内容(在本例中是承诺),我直接从Firebase调用该函数,但是现在不再从Firebase调用它,而不是从Firebase调用它,它只是用我刚才定义的假数据返回“假”Promise。https://stackoverflow.com/questions/69016688
复制相似问题