Firebase 应用的 Mocha 单元测试

Mocha unit tests for Firebase app

我使用 firebase 3.3.0,我想在我的 mocha 单元测试中使用 signInWithEmailAndPassword 函数,但是我得到错误 auth/network-request-failed

Unhandled rejection Error: A network error (such as timeout, interrupted connection or unreachable host) has occurred. 

test.js

const FIREBASE_CONFIG = {
    apiKey: "AIzaSyDdA1POUWy9eid1AdBYuMdxch_k8ob7Qrg",
    authDomain: "my-app.firebaseapp.com",
    databaseURL: "https://my-app.firebaseio.com",
    storageBucket: "my-app.appspot.com",
};

const FIREBASE_API_REF = firebase.initializeApp(FIREBASE_CONFIG);

before(function (done) {

        promise = new Promise(function (resolve, reject) {
            return FIREBASE_API_REF.auth().signInWithEmailAndPassword(firstUserEmail, firstUserPassword)
            .then(function (userData) {
                firstUserId = userData.uid;
                resolve(userData);
                done();
            }, function (error) {
                return reject(error);
            })
        });

    });

package.json

"scripts": {
    "test": "mocha --grep ./e2e.js --invert --compilers js:babel-register -R spec --ui bdd --timeout 7000"
  }

当你说,"I want to use signInWithEmailAndPassword function in my mocha unit test"那么我会对你说,"why"?

您是否正在尝试通过测试他们的身份验证服务是否有效来帮助 Firebase 团队?你真好,但如果你想测试你的应用程序,那么你应该 NOT 在单元测试中完全调用 firebase。您真正想要检查的是,一旦响应返回,您的应用程序在 运行 代码中正确处理了类似于 Firebase 响应的响应。

如果我的任务是为此编写测试,我会使用带有 mocha 的 sinon 库并创建一个调用不同函数的存根 returns 一些数据而不是实际调用 Firebase:

这说明了 sinon 存根的语法:

var stub = sinon.stub(object, "method", func);

这就是我在你的例子中要做的:

var stub = sinon.stub(FIREBASE_API_REF.auth(), "signInWithEmailAndPassword"
,  () => { 

  // Simply return a JSON object that is similar to the normal response from Firebase
  return {
    name: "Jim",
    data: {
      something: "some stuff"
    }
});

可能您不再需要它了,但我没有创建存根,而是使用了 spyOn,它的效果非常好。

对于遇到此问题的任何其他人,我能够确定问题来自 jsdom 的全局 XMLHttpRequest 对象。通过使用此代码设置我的全局变量,我能够摆脱错误:

var doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = doc.defaultView;

for (var key in window) {
  if (!window.hasOwnProperty(key)) continue;
  if (key in global) continue;
  if (key == 'XMLHttpRequest') continue;

  global[key] = window[key];
}