【问题标题】:Unit test a polymer web component that uses firebase对使用 firebase 的聚合物 Web 组件进行单元测试
【发布时间】:2016-09-27 14:39:45
【问题描述】:

我一直在尝试为使用最新版本 Firebase 分布式数据库的聚合物 Web 组件配置离线单元测试。我的一些测试通过了,但其他的——看起来与通过的测试几乎相同——运行不正常。

我在 github 上建立了一个项目来演示我的配置,我将在下面提供更多评论。

示例: https://github.com/doctor-g/wct-firebase-demo

在那个项目中,有两套测试工作正常。最简单的是offline-test,它根本不使用Web 组件。它只是表明可以使用 firebase 数据库的离线模式来运行一些单元测试。这个技巧的核心是下面显示的suiteSetup 方法中的一个技巧——我从nfarina's work on firebase-server 中学到的一个技巧。

suiteSetup(function() {
  app = firebase.initializeApp({
      apiKey: 'fake',
      authDomain: 'fake',
      databaseURL: 'https://fakeserver.firebaseio.com',
      storageBucket: 'fake'
  });
  db = app.database();

  db.goOffline();
});

offline-test 中的所有测试均通过。

下一个套件是wct-firebase-demo-app_test.html,用于测试同名的 Web 组件。该套件包含一系列单元测试,这些单元测试设置为 offline-test 并通过。遵循依赖注入的想法,wct-firebase-demo-app 组件有一个 database 属性,将 firebase 数据库引用传递给该属性,用于进行所有 firebase 调用。这是套件中的一个示例:

  test('offline set string from web component attribute', function(done) {
    element.database = db;
    element.database.ref('foo').set('bar');
    element.database.ref('foo').once('value', function(snapshot) {
      assert.equal(snapshot.val(), 'bar');
      done();
    });
  });

我在组件中也有一些非常简单的方法,以尝试对我稍后会谈到的破碎部分进行三角测量。只要说这个测试通过就够了:

test('offline push string from web component function', function(done) {
    element.database = db;
    let resultRef = element.pushIt('foo', 'bar');
    element.database.ref('foo').once('value', function(snapshot) {
      assert.equal(snapshot.val()[resultRef.key], 'bar');
      done();
    });
  });

并由wct-firebase-demo-app 中的此实现支持:

  pushIt: function(at, value) {
    return this.database.ref(at).push(value);
  },

再一次,这些都过去了。现在我们进入了真正的困境。对于另一个元素 x-element 有一套测试,它有一个方法 pushData

  pushData: function(at, data) {
    this.database.ref(at).push(data);
  }

这个方法的测试是its suite中唯一的测试:

  test('pushData has an effect', function(done) {
    element.database = db;
    element.pushData('foo', 'xyz');
    db.ref('foo').once('value', function(snapshot) {
      expect(snapshot.val()).not.to.be.empty;
      done();
    });
  });

此测试未通过。在运行此测试时,控制台会显示一条错误消息:

    Your API key is invalid, please check you have copied it correctly.

通过设置一些断点并遍历执行,在我看来这个错误是在调用 once 之后但在触发回调之前出现的。请再次注意,这不会发生在与上述 wct-firebase-demo-app 中相同的测试结构中。

这就是我卡住的地方。为什么offline-testwct-firebase-demo-app_test 套件工作正常,但我在x-element_test 中收到此API 密钥错误?我唯一的其他线索是,如果我将有效的 API 密钥复制到我的 initializeApp 配置中,那么我会得到一个测试超时。

更新:

这是运行测试时我的控制台日志的(拼凑在一起的)图像。:

为了说明下面 tony19 提出的问题,下面是控制台日志,其中 x-element_test 中的 pushData has an effect 被注释掉了:

【问题讨论】:

  • 啊,非常有用的观察@tony19!我一直信任 wct 输出而不查看控制台日志。也许它比我预期的更像纸牌屋。

标签: unit-testing firebase polymer web-component-tester wct


【解决方案1】:

offline-test 结果显然是误报。如果您检查 Chrome 控制台,offline-test 实际上会抛出相同的错误:

该错误很可能不会影响测试结果,因为 API 密钥验证在测试完成后异步发生。如果您能以某种方式挂钩该验证,您将能够在测试中发现错误。

注释掉除offline firebase is ok 之外的所有测试表明错误仍在发生,它指向suiteSetup()。通过在设置中注释 3 个函数调用中的 2 个来进一步缩小问题范围,我们将看到错误是由对 firebase.initializeApp() 的调用引起的(并且不一定与您所怀疑的 once() 相关)。

要考虑的一种解决方法是将 Firebase 库包装在一个类/接口中,然后模拟它以进行单元测试。

【讨论】:

  • 这与我在这里看到的行为不同:如果我注释掉除 offline firebase is ok 之外的所有测试,那么一切正常,不会引发任何 API 错误。事实上,如果我只在x-element_test 中注释掉pushData has an effect,那么整个套件运行时不会在控制台中产生任何警告或错误。
  • 我很好奇 x-element_test.html 中的更改会对 offline-test.html 产生什么影响。我在提交 e5d1d55 时在 OSX El Capitan、Chrome 51 上看到的行为对我来说很容易重现。
  • 另外澄清一下,我通过打开offline-test.html 运行offline-test。我假设您根据屏幕截图以不同的方式运行它。当您单独打开该文件时,您发现有什么不同吗?
  • 我通过polymer test 运行测试,它是wct 的包装器。
  • 在 Chrome 中单独运行 offline-test.html,我得到与您在此处发布的内容类似的输出,尽管具体错误及其位置不同。可能最重要的是,在 getProjectConfig 调用中有一个 400。它以“您的 API 密钥无效”结尾。 Chrome 51,Linux Mint 17。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多