如何模拟一个将有 then 和 catch 块的函数?
How to mock a function that will have then and catch block?
我使用 Firebase 身份验证,我想使用 Jest 和 react-hooks-testing-library 测试功能。
我有一个这样的函数:
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()
的 return 的模拟应该没问题,但它仍然有错误。
我是测试领域的新手。请有人对此提出一些建议并告诉我我的测试有什么问题?我完全不知道
在寻找这个 :
之后,我试图像这样模拟它
const mockSomething = jest.fn().mockImplementation(() => Promise.resolve({
user: {
uid: "fakeuid",
},
}))
但还是出现同样的错误
最后我能够通过模拟函数来解决问题 return promise that resolved with user
like this:
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
中,我直接 return 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')
在测试中,我必须直接从 firebase/auth
调用 signInWithEmailAndPassword
。
因为我已经mock了jest.mock()
中的函数,所以在测试中它会return返回我直接定义的假数据,即data: { user: { uid: 'fakeUid' } }
整个过程是这样的:
firebase/auth
模块中有一个名为 signInWithEmailPassword
的实际函数
- 但我不想“真的”调用它,因此我创建了一个具有相同名称的假函数,它将 return 与 [=18= 中的实际函数相同的东西(在本例中为 Promise) ]
- 现在,在
test
部分,我直接从 Firebase 调用函数,但现在不是“实际”从 Firebase 调用它,它只是 return “假”Promise
用我刚才定义的假数据。
- 然后我可以使用
expect(data.user.uid).toEqual('fakeUid')
将它与一个值进行比较
我使用 Firebase 身份验证,我想使用 Jest 和 react-hooks-testing-library 测试功能。
我有一个这样的函数:
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()
的 return 的模拟应该没问题,但它仍然有错误。
我是测试领域的新手。请有人对此提出一些建议并告诉我我的测试有什么问题?我完全不知道
在寻找这个
const mockSomething = jest.fn().mockImplementation(() => Promise.resolve({
user: {
uid: "fakeuid",
},
}))
但还是出现同样的错误
最后我能够通过模拟函数来解决问题 return promise that resolved with user
like this:
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
中,我直接 return 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')
在测试中,我必须直接从 firebase/auth
调用 signInWithEmailAndPassword
。
因为我已经mock了jest.mock()
中的函数,所以在测试中它会return返回我直接定义的假数据,即data: { user: { uid: 'fakeUid' } }
整个过程是这样的:
firebase/auth
模块中有一个名为signInWithEmailPassword
的实际函数
- 但我不想“真的”调用它,因此我创建了一个具有相同名称的假函数,它将 return 与 [=18= 中的实际函数相同的东西(在本例中为 Promise) ]
- 现在,在
test
部分,我直接从 Firebase 调用函数,但现在不是“实际”从 Firebase 调用它,它只是 return “假”Promise
用我刚才定义的假数据。 - 然后我可以使用
expect(data.user.uid).toEqual('fakeUid')
将它与一个值进行比较