如何模拟 firebase.auth.UserCredential 笑话?

Phi*_*hil 2 javascript unit-testing firebase typescript jestjs

这是我当前的模拟,我想createUserWithEmailAndPassword返回firebase.auth.UserCredential,这样我就可以测试它是否在我的中被调用App.ts

应用程序规范

import myAuthenticationPlugin from 'authenticationPlugin/App'
import firebase from 'firebase/app'
jest.mock('firebase/app', () => {
  return {
    auth: jest.fn().mockReturnThis(),
    currentUser: {
      email: 'test',
      uid: '123',
      emailVerified: true
    },

    signInWithEmailAndPassword: jest.fn(),
    createUserWithEmailAndPassword:jest.fn(() => {
      return {
        user:{
          sendEmailVerification:jest.fn(),
        },
      }
    }),
    initializeApp:jest.fn()
  };
});

 describe('Test for signup (email,password)',() => {

    it('createUserWithEmailAndPassword ()',async () => {  //this works
      await myAuthenticationPlugin.signup(email, password)
      expect(firebase.auth().createUserWithEmailAndPassword).toBeCalledWith(email, password)
    })

    it('sendEmailVerification()',async ()=>{
      await myAuthenticationPlugin.signup(email, password)
      const userCredential= await firebase.auth().createUserWithEmailAndPassword(email,password)
      if(userCredential.user!=null){
      expect(userCredential.user.sendEmailVerification).toBeCalled() //this fails as i'm not able to mock properly
      }
    })
  })
Run Code Online (Sandbox Code Playgroud)

应用程序.ts

import firebase from 'firebase/app'
import 'firebase/auth'
import './Init'
const App= {
 signup: async (email, password) => {
    const userCredential = await firebase.auth().createUserWithEmailAndPassword(email, password)
    await userCredential.user.sendEmailVerification()
    return `Check your email for verification mail before logging in`
  },
}
export default App
Run Code Online (Sandbox Code Playgroud)

sli*_*wp2 5

这是单元测试解决方案:

\n\n

app.ts:

\n\n
import firebase from \'firebase/app\';\n\nconst App = {\n  signup: async (email, password) => {\n    const userCredential = await firebase.auth().createUserWithEmailAndPassword(email, password);\n    await userCredential.user!.sendEmailVerification();\n    return `Check your email for verification mail before logging in`;\n  },\n};\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n\n

app.test.ts:

\n\n
import App from \'./app\';\nimport firebase from \'firebase/app\';\n\nconst userCredentialMock = {\n  user: {\n    sendEmailVerification: jest.fn(),\n  },\n};\n\njest.mock(\'firebase/app\', () => {\n  return {\n    auth: jest.fn().mockReturnThis(),\n    createUserWithEmailAndPassword: jest.fn(() => userCredentialMock),\n  };\n});\n\ndescribe(\'61391590\', () => {\n  afterAll(() => {\n    jest.resetAllMocks();\n  });\n  it(\'should pass\', async () => {\n    const email = \'example@gmail.com\';\n    const password = \'123\';\n    const actual = await App.signup(email, password);\n    expect(actual).toEqual(\'Check your email for verification mail before logging in\');\n    expect(firebase.auth().createUserWithEmailAndPassword).toBeCalledWith(email, password);\n    expect(userCredentialMock.user?.sendEmailVerification).toBeCalled();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

100%覆盖率的单元测试结果:

\n\n
 PASS  stackoverflow/61391590/app.test.ts (12.946s)\n  61391590\n    \xe2\x9c\x93 should pass (7ms)\n\n----------|---------|----------|---------|---------|-------------------\nFile      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------|---------|----------|---------|---------|-------------------\nAll files |     100 |      100 |     100 |     100 |                   \n app.ts   |     100 |      100 |     100 |     100 |                   \n----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        14.863s\n
Run Code Online (Sandbox Code Playgroud)\n\n

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61391590

\n

  • 我必须将 `const userCredentialMock` 移到 `jest.mock` 内,否则它会抛出一个错误。。。。babel-plugin-jest-hoist:`jest.mock()` 的模块工厂不允许引用任何超出范围的变量。无效的变量访问:userCredentialMock (2认同)