在前端测试 react + redux 应用程序时忽略与浏览器相关的变量

Ignoring browser-related variables while frontend testing react + redux app

我目前正在使用 mocha 对我的 react/redux 应用程序进行前端测试。

好像每当我的函数中有与浏览器相关的变量时,测试就会失败。

例如,我的一个函数如下所示:

export const loginUserSuccess = (token, user) => {
    localStorage.setItem('token', token); // browser-related variable here
    return {
        type: LOGIN_USER_SUCCESS,
        payload: {
            token: token,
            user: user
        }
    }
}

注意我对 localStorage 的使用。这个变量显然在测试时不可用,所以任何碰巧触发 loginUserSuccess 动作的测试都不会通过。老实说,我根本不需要测试 localStorage 逻辑——我只想要 return 正确的操作。但即使我这样做:

if (localStorage) localStorage.setItem('token', token);

我仍然收到一条错误消息,提示 localStorage 未定义。 如何让测试模块忽略某些变量?

另一个例子是当一个动作调用全局window。在进行 API 调用时,我的操作会查看 window 以查看将请求发送到哪里:

export const createUserInAuthStore = (username, password) => {

    let url = `${window.__BASE_URL__}/auth/user/` // look at the window here
    let data = { username, password }

    return request
      .post(url)
      .type('form')
      .send(data)
      .end()
      .then((response) => {
        return {
            token: response.body.token,
            username
        }
      })
      .catch((error) => Promise.reject(error))
}

显然 mocha 抱怨 window 在第 3 行未定义。但即使我将该行修复为:

let baseurl = window ? window.__BASE_URL__ : 'api.dockerhost'

mocha 继续抛出错误。

TL;DR: 有没有办法在测试时忽略或替换浏览器相关的变量?

在 mocha 中,所有全局可用的变量都带有前缀 global。所以要嘲笑你的localStorage,你可以这样做

global.localStorage = {
    setItem: function () {}
}

对于您的 window,您可以这样做:

global.window = {
    __BASE_URL__: "/bla/whatever"
}

并且不要忘记在之后再次删除它们以避免影响其他测试(我通常在 afterEach() 函数中这样做)。