如何模拟window.gapi.load()React + Jest

时间:2020-04-28 14:20:16

标签: reactjs google-api jestjs enzyme google-api-js-client

对于Angular,有一个问题可以回答这个问题;对于Vuejs,有一个没有任何答案的问题。我正在尝试寻找一种在测试中模拟window.gapi.load()函数的方法。我是React测试的新手,这是我到目前为止的东西:

it('should render the App component without crashing', function () {
  const component = renderer.create(
    shallow(
      <Root>
        <App/>
      </Root>
    )
  )

  let tree = component.toJSON()
  expect(tree).toMatchSnapshot()
})

我已经尝试了一个基本的beforeEach调用来尝试加载它或其他东西,但是那也不起作用。这是组件中的代码:

const App = () => {
  const { isSignedIn } = useSelector(state => state.auth)

  const renderApp = () => {
    if (isSignedIn) {
      return <Home/>
    } else {
      return (
          <div className='app'>
            <h1 id='logo'>netTube</h1>
            <GoogleAuth/>
          </div>
      )
    }
  }

  return (
      <>
        { renderApp() }
      </>
  )
}

以及GoogleAuth组件中的调用:

// GoogleAuth.jsx

componentDidMount() {
    window.gapi.load('client:auth2', () => {
      window.gapi.client.init({
        clientId: process.env.REACT_APP_GOOGLE_CLIENT_ID,
        scope: 'email'
      }).then(() => {
        this.auth = window.gapi.auth2.getAuthInstance()
        this.onAuthChange(this.auth.isSignedIn.get())
        this.auth.isSignedIn.listen(this.onAuthChange)
      })
    })
  }

如果您想让我添加其他内容,请询问。很抱歉,如果没有足够的信息,就像我说的那样,我对React测试来说是新手。谢谢!

3 个答案:

答案 0 :(得分:1)

您可以仅模拟组件使用的每个gapi调用。 (尽管使用浅层渲染,您的componentDidMount可能无法运行。)

类似:

window.gapi = {};
window.gapi.auth2.getAuthInstance = () => {isSignedIn : {get : () => true, listen : f => f()}};
window.gapi.client.init = (v) => true;
window.gapi.load = (a, f) => f();

作为it的第一行(甚至在每个func之前/之前更好)

答案 1 :(得分:1)

对 Tom & Hector 的回答进行一些扩展,我添加了一个 JWT 令牌,它似乎在 Jest 中可以用于模拟登录和退出 gapi.auth2 的基础知识:

window.gapi = {auth2: {}, client: {}};
window.gapi.auth2.getAuthInstance = () => {return new function() {
  this.isSignedIn = new function() {
    this.signedIn = false;
    this.get = () => this.signedIn;
    this.listen = (f) => f();
  };
  this.signIn = () => Promise.resolve(this.isSignedIn.signedIn = true);
  this.signOut = () => Promise.resolve(this.isSignedIn.signedIn = false);
  this.currentUser = new function() {
    this.get = () => new function() {
      this.getId = () => "XYZ";
      this.getAuthResponse = () => new function() {
        this.id_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
      };
      this.getBasicProfile = () => new function() {
        this.getName = () => "Mr Test";
        this.getEmail = () => "test@email.com";
        this.getImageUrl = () => "http://email.com/image";
      };
    };
  };
};}
window.gapi.auth2.init = () => {return Promise.resolve({});}
window.gapi.client.init = (v) => true;
window.gapi.load = (a, f) => f();

答案 2 :(得分:0)

这就是我在Jest中为window.gapi.auth2.getAuthInstance模拟数据的方式。您可以做同样的事情。

示例:

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import {BrowserRouter} from 'react-router-dom';

import Home from "../routes/Home";

let container = null;
beforeEach(() => {
    // setup a DOM element as a render target

    let profileObj = {
        getEmail: () => 'testUser@gmail.edu',
        getImageUrl: () => 'www.example.com/stem.jpg',
        getName : () => 'NON STEM user'
    }

    let getBasicProfileFun = { getBasicProfile: () => profileObj }

    let authInstanceObj = { 'currentUser': { get: () => getBasicProfileFun } }
    window.gapi = { 'auth2': "d" };
    window.gapi.auth2 = { getAuthInstance: () => authInstanceObj }

    container = document.createElement("div");
    document.body.appendChild(container);
});

afterEach(() => {
    // cleanup on exiting
    unmountComponentAtNode(container);
    container.remove();
    container = null;
});

it("renders with or without a name", () => {
    act(() => {
        render(<BrowserRouter><Home /></BrowserRouter>, container);
    });
    // console.log(container)
    expect(container.textContent).toBe(' PairStudytestUser@gmail.eduWelcome to Pair StudySelect your field of study and join a roomStemNon-StemJoin Room');
});