【问题标题】:How to Write Unit Tests for Functions That Contain SAPUI5 Core API?如何为包含 SAPUI5 Core API 的函数编写单元测试?
【发布时间】:2018-05-12 19:03:38
【问题描述】:

我是使用 UI5 的 qUnit 的新手。

我想测试一个函数formatter.js

formatDate: function(sTimeStamp) {
  if (sTimeStamp) {
    var iTimeStamp = Number(sTimeStamp.match(/\d/g).join("")), 
        oDateTimeFormat = DateFormat.getDateTimeInstance(); 
    return oDateTimeFormat.format(new Date(iTimeStamp));
  }
  return sTimeStamp;
},

对其进行单元测试:

function formatDateTestCase(assert, sValue, fExpectedNumber) {
  var fDate = formatter.formatDate(sValue);
  assert.strictEqual(fDate, fExpectedNumber, "Format Date was correct");
}

QUnit.test("Should return valid date", function (assert) {
  formatDateTestCase.call(this, assert, "/Date(1510026665790)/", "Nov 7, 2017, 11:51:05 AM");
});

显然,当我更改语言设置时,此测试用例将失败。如何改进它?


我认为这里的主要问题是formatDate 是一个有副作用的函数。我应该改进这个功能本身吗?通过在formatDate 中添加语言环境?

或者我应该在我的测试用例中使用DateFormat 吗?这将使我的测试毫无意义。

【问题讨论】:

  • 为什么要为 UI5 核心功能编写测试用例?您的测试只会证明 SAP 的代码可以正常工作(并且您了解他们的 API)。
  • @Marc,1. 用于测试覆盖率。 2.我这里只是举个简单的例子,可能还有其他复杂的逻辑包含DateFormat,如何stub呢?

标签: javascript unit-testing sapui5 sinon qunit


【解决方案1】:

我认为您应该在此处模拟对DateFormat 的调用,以便能够独立测试您的代码。

单元测试注意事项

严格来说,单元测试的目的是测试您的 - 并且只测试您的 - 单元。你不应该测试任何依赖的 API。一般来说,人们可能会争论这一点,但我绝对不建议测试 SAPUI5 API。

另一方面,我强烈建议使用无效参数(例如 undefined)和无效字符串来测试 if 语句和正则表达式部分。这将确保您的格式化程序始终工作并返回某事。如果是空字符串,则有意义。

Sinon.JS:模拟、存根和间谍

您应该在您的特定测试中存根DateFormat.getDateTimeInstance(),以便该方法返回一个可预测的值(例如,想想DateFormat 中的I18N,它会给您不同语言的不同测试结果)。

为此,SAPUI5 已经附带Sinon.JS(请注意包含的版本:SAPUI5 1.44 -> Sinon.JS 1.14)。这是一个基本示例:

sap.ui.define([
  "my/module/formatter",
  "sap/ui/core/format/DateFormat",
  "sap/ui/thirdparty/sinon",
  "sap/ui/thirdparty/sinon-qunit"
], function (formatter, DateFormat) {

  QUnit.test("Should return valid date", function (assert) {
    // stub the method
    sinon.stub(DateFormat, "getDateTimeInstance");
    // ensure a predictable outcome
    DateFormat.getDateTimeInstance.returns({
      format: function(oDate) {
        return oDate.getTime();
      }
    });

    var fDate = formatter.formatDate("/Date(1510026665790)/");
    assert.strictEqual(fDate, "1510026665790", "Format Date was correct");
    // Optional: test if the stubbed function was called
    assert.ok(DateFormat.getDateTimeInstance.calledOnce);

    // don't forget to restore the stub so that it does not interfere with other tests
    DateFormat.getDateTimeInstance.restore();
  });

});

通过存根DateFormat.getDateTimeInstance,您可以停止测试核心 API 及其结果,您可以专注于最重要的事情:您的代码。

BR克里斯

【讨论】:

  • 我应该存根oDataModel.read/create/createEntry/update/remove 吗?
  • 您不应在单元测试中依赖后端或特定后端响应。您还可以使用模拟服务器并修复模拟数据。一般来说,模拟这些东西可能比模拟它更容易。也取决于您的单元测试方法(纯单元测试与使用单元测试工具的集成测试)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 2017-02-15
相关资源
最近更新 更多