【问题标题】:How to test correct data validation with Mocha using Loopback?如何使用 Loopback 使用 Mocha 测试正确的数据验证?
【发布时间】:2019-06-17 21:22:06
【问题描述】:

我正在为已经存在的代码设置测试。我想测试为对象创建数据库条目,特别是在给出 incorrect 参数时 create()-Method 的行为方式。当尝试使用故意不正确的参数创建对象时,Loopback upsert()-方法(由我们的 create()-方法使用)在我断言行为之前会引发错误。

我们使用 Node、Express 和 Loopback 作为后端,使用 Mocha 和 Chai 作为测试套件。我们在对象的模型中使用了 Loopback 选项“validateUpsert:true”,这可能会导致抛出上述错误。

基本模型如下所示:

{
  "name": "Field",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "numberOfSpots": {
      "type": "number",
      "required": true
    }
}

所以我在 Mocha 中的测试用例看起来像下面的代码。注意 numberOfSpots 旁边的注释:

it('should return null upon entering false data', async() => {
  // Given
  const givenFieldData = {
    numberOfSpots: 'two' // Using text instead of a number
  }

  // When
  const newField = await Field.create(givenFieldData);

  // Then
  assert.isNull(newField);

});

Field.create(givenFieldData)基本上是在将givenFieldData转化为Field-Object之后调用这个Loopback方法:

FieldModel.upsertWithWhere(where, Field)
    .catch(error => logger.error(error))
    .finally(return null);

现在我希望断言会运行,但实际上从未执行过。 finally 块似乎也没有被执行。控制台记录如下内容:

ERROR (ValidationError/3844 on M): The instance `Field` is not valid. Details: `numberOfSpots` can't be blank (value: NaN).

现在测试失败了,尽管行为是正确的,即没有创建对象。我需要找到一种方法来检查对象是否(正确)未创建,这应该通过通过测试来反映。谢谢!

【问题讨论】:

    标签: node.js validation testing mocha.js loopback


    【解决方案1】:

    Field.create(givenFieldData)基本上是在将givenFieldData转化为Field-Object之后调用这个Loopback方法:

    FieldModel.upsertWithWhere(where, Field)
      .catch(error => logger.error(error))
      .finally(return null);
    

    第一个问题在于您的 Field.create 方法,它有效地丢弃错误并将它们转换为成功结果。

    发生错误时,您的catch 回调将其打印到控制台并隐式返回undefined。结果,外层promise最终返回给undefined

    finally 回调返回的值总是被忽略。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

    就个人而言,我不会尝试处理您的 create 方法中的错误,并将错误处理留给调用者。

    class Field {
      create() {
        return FieldModel.upsertWithWhere(where, Field);
      }
    }
    

    然后在测试中,您应该验证 create 返回的承诺最终会因预期错误而被拒绝。例如,使用should.js:

    it('should return null upon entering false data', async() => {
      // Given
      const givenFieldData = {
        numberOfSpots: 'two' // Using text instead of a number
      }
    
      Field.create(givenFieldData).should.be.rejectedWith(
        /`numberOfSpots` can't be blank/
      );
    });
    

    如果您希望丢弃错误并返回null,那么您可以实现Field.create,如下所示:

    class Field {
      async create() {
        try {
         return await FieldModel.upsertWithWhere(where, Field);
        } catch(err) {
          if (err.name !== 'ValidationError') {
            // re-throw non-validation errors 
            // (e.g. cannot connect to the database)
            throw err;
          }
    
          logger.error(error);
          return null;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-05
      • 2014-12-21
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多