Ad

Test Firebase Authenticate Using Google Sign-In In Jest

- 1 answer

I cannot figure out how to jest mock firebase authentication with google login properly.I have the following code:

simple.tsx

import React, { Component } from 'react';
import * as firebase from 'firebase'
import { withRouter} from 'react-router-dom';

class simple extends Component {

  signInWithgoogle() {
    var provider = new firebase.auth.GoogleAuthProvider();
    // how to mock provider when simulate click event.
    firebaseApp.auth().signInWithRedirect(provider)

  }

  render() {
    return (
      <div>
        <button onClick={this.signInWithgoogle.bind(this)}>
          Login with Google
        </button>
      </div>

    );
  }
export default withRouter(connect(
)(simple));

simple.test.tsx

const mockStore = configureMockStore([thunk]);
const store = mockStore();

describe('<simple />', () => {
    test("simulate click button", () =>{
        const withProvider = (
            <Provider store={store}>
                <simple.WrappedComponent {...FirebaseAuthProps} />
            </Provider>
        );

        const wrapper = mount(withProvider);
        wrapper.find('Button').simulate('click');
    });
});

Any help would be appreciated with examples?

Ad

Answer

Typescript namespace is some kind of a JS function after compiling and type erasure. After knowing this, of course, you can assign properties to JS function. Here is the solution:

simple.tsx:

import React, { Component } from 'react';
import firebase from 'firebase';
import { withRouter } from 'react-router-dom';

class simple extends Component {
  signInWithgoogle() {
    var provider = new firebase.auth.GoogleAuthProvider();
    firebase.auth().signInWithRedirect(provider);
  }

  render() {
    return (
      <div>
        <button onClick={this.signInWithgoogle.bind(this)}>Login with Google</button>
      </div>
    );
  }
}

export default withRouter(simple as any);

simple.spec.tsx:

import React from 'react';
import { mount } from 'enzyme';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import simple from './simple';
import firebase from 'firebase';

const mockStore = configureMockStore([thunk]);
const store = mockStore();
const FirebaseAuthProps = {};

jest.mock('firebase', () => {
  const auth = jest.fn();
  const mAuth = { signInWithRedirect: jest.fn() };
  // @ts-ignore
  auth.GoogleAuthProvider = jest.fn();
  // @ts-ignore
  auth.Auth = jest.fn(() => mAuth);
  return { auth };
});

describe('<simple />', () => {
  afterEach(() => {
    jest.resetAllMocks();
  });
  test('simulate click button', () => {
    // @ts-ignore
    firebase.auth.mockImplementation(() => new firebase.auth.Auth());
    const withProvider = (
      <Provider store={store}>
        <simple.WrappedComponent {...FirebaseAuthProps} />
      </Provider>
    );

    const wrapper = mount(withProvider);
    expect(wrapper.find('button').text()).toBe('Login with Google');
    wrapper.find('button').simulate('click');
    expect(firebase.auth.GoogleAuthProvider).toBeCalledTimes(1);
    expect(firebase.auth).toBeCalledTimes(1);
    expect(firebase.auth().signInWithRedirect).toBeCalledTimes(1);
  });
});

Unit test result with 100% coverage:

 PASS  src/stackoverflow/58554920/simple.spec.tsx (15.341s)
  <simple />
    ✓ simulate click button (82ms)

------------|----------|----------|----------|----------|-------------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------|----------|----------|----------|----------|-------------------|
All files   |      100 |      100 |      100 |      100 |                   |
 simple.tsx |      100 |      100 |      100 |      100 |                   |
------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        17.245s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58554920

Ad
source: stackoverflow.com
Ad