首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟一个函数,然后有和捕捉块?

如何模拟一个函数,然后有和捕捉块?
EN

Stack Overflow用户
提问于 2021-09-01 15:28:40
回答 1查看 680关注 0票数 2

我使用Firebase身份验证,我想使用Jest和react挂钩测试-库来测试这个函数。

我有一个这样的功能:

代码语言:javascript
复制
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()块。

我用下面的代码来模拟这个函数:

代码语言:javascript
复制
const mockSignUp = jest.fn(() => {
    return Promise.resolve({
        user: {
            uid: "fakeuid",
        },
    });
})

jest.mock('firebase/auth', () => ({
    getAuth: () => mockGetAuth,
    signInWithEmailAndPassword: () => mockSignIn,
    createUserWithEmailAndPassword: () => mockSignUp
}))

然后使用react-hooks-testing-library测试上面的函数,如下所示:

代码语言:javascript
复制
 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)
    })

然后我的测试失败了,因为这个错误:

代码语言:javascript
复制
 TypeError: (0 , _auth.signInWithEmailAndPassword)(...).then is not a function

      46 |
      47 |         signInWithEmailAndPassword(auth, email, password)
    > 48 |             .then((userCredential) => {

如果我删除then块,测试就通过了。但是,如果我使用调用的then()作为函数,它就会得到错误。我检查返回signInWithEmailAndPasswordPromise.resolve()的模拟是否正常,但它仍然存在错误。

我是测试领域的新手。请有人对此提出一些建议,并告诉我的测试有什么问题吗?我完全不知道

在寻找这个answer之后,我试着像这样嘲弄它

代码语言:javascript
复制
const mockSomething = jest.fn().mockImplementation(() => Promise.resolve({
    user: {
        uid: "fakeuid",
    },
}))

但仍然有同样的错误

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-01 18:34:08

最后,我能够通过模拟一个函数来解决这个问题,这个函数将返回用user解决的承诺,如下所示:

代码语言:javascript
复制
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()包装它

在测试中,我可以这样做:

代码语言:javascript
复制
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

  • But模块中有一个名为
  • 的实际函数,我不想“真的”调用它,因此我用相同的名称制作了一个假函数,它将返回jest.mock()
  • Now,内部的实际函数在test部分中的相同内容(在本例中是承诺),我直接从Firebase调用该函数,但是现在不再从Firebase调用它,而不是从Firebase调用它,它只是用我刚才定义的假数据返回“假”Promise
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69016688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档