【问题标题】:Why can't I use an anonymous function inside jasmine's expectAsync?为什么我不能在 jasmine 的 expectAsync 中使用匿名函数?
【发布时间】:2021-02-11 10:15:44
【问题描述】:

我正在尝试在 Jasmine 中为我的 Nodejs Mongoose 模型进行单元测试。除非我将代码从功能块转移到匿名/箭头函数,否则一切正常。我不明白为什么它不能使用匿名/箭头函数。

这是我的基本规范文件:

const MongoDbTest = require('../lib/mongodb-tests.lib');
const Info = require("../models/info.model");

async function addTupleWithoutValue() {
  await new Info({ name: 'trududu' }).save();
}

describe("Le modèle Info", () => {
  const mongod = new MongoDbTest();

  beforeAll(async () => {
    await mongod.connect(); // This takes care of connecting to the database, etc.
  } );

  afterAll(async () => {
    await mongod.close(); // This takes care of closing the connection, etc.
  } );

  // ... other tests removed

  it("a absolument besoin du champ 'value'", async () => {
    await expectAsync(async function() {
      await new Info({ name: 'trududu' }).save();
    } ).toBeRejectedWithError(/value: Path `value` is required/); // This does not work

    await expectAsync(addTupleWithoutValue()).toBeRejectedWithError(/value: Path `value` is required/); // this works
  } );
} );

这是我的模型:

const mongoose = require('mongoose');
const Mixed = mongoose.Mixed;

const InfoSchema = new mongoose.Schema( {
  name: { type: String, unique: true },
  value: { type: Mixed, required: true }
} );

module.exports = mongoose.model('Info', InfoSchema);

当我使用匿名函数(或箭头函数)时,Jasmine 给我以下错误消息:Error: Expected toBeRejectedWithError to be called on a promise. 查看 Jasmine 的源代码,函数返回的值由 function(obj) { return !!obj && j$.isFunction_(obj.then); } 检查。这是否意味着匿名函数返回不同类型的承诺?

【问题讨论】:

    标签: javascript node.js unit-testing mongoose jasmine


    【解决方案1】:

    原来我忽略了匿名函数和函数块之间的一个微小差异。你发现了吗?这里是:

    await expectAsync(async function() {
      await new Info({ name: 'trududu' }).save();
    } ).toBeRejectedWithError(/value: Path `value` is required/); // This does not work
    
    await expectAsync(addTupleWithoutValue()).toBeRejectedWithError(/value: Path `value` is required/); // this works
    

    第二个有一个额外的(),这意味着该函数被调用并返回一个promise。第一个是简单的函数定义,这意味着 toBeRejectedWithError 失败是因为它需要一个承诺,而不是一个函数。

    通过在匿名函数定义后添加(),将其更改为函数call(返回一个promise),一切都像一个魅力。

    我在发布我的问题之前解决了这个问题,但我决定完成发布它,因为我没有找到任何类似的问题。我希望这对其他开发人员有所帮助。

    【讨论】:

    • 您缺少的是函数定义和函数调用之间的区别。看起来expectAsync 没有将函数作为参数,而是将Promise 类型的值。
    • 实际上,由于expectAsync 需要一个promise,所以将它包装在async/await 中是完全多余的:await expectAsync(new Info({name:'trududu'}).save()) 是最好的写法
    • 是的,在这种特殊情况下,您是对的。我的大多数测试都包含几个语句。感谢您对函数调用的精确度,我将编辑我的答案。
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2011-03-21
    相关资源
    最近更新 更多