Sequelize - 测试使用虚拟字段更新模型

问题描述 投票:0回答:1

我有以下型号:

    const Invoice = sequelize.define("invoice", {
        number: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: { msg: "Invoice number already exists" },
            validate: { ...notEmptyMsg("Invoice number") },
        },
        dateIssued: {
            type: DataTypes.DATE,
            allowNull: false,
            validate: isDateMsg("dateIssued"),
        },
        dueDate: {
            type: DataTypes.DATE,
            allowNull: false,
            validate: {
                ...isDateMsg("dueDate"),
                isAfterDateIssued(value) {
                    if (this.dateIssued && value < this.dateIssued) {
                        throw new Error("Due date cannot be before the date issued");
                    }
                },
            },
        },
        sender: {
            type: DataTypes.TEXT,
            allowNull: false,
            validate: notEmptyMsg("Sender"),
        },
        recipient: {
            type: DataTypes.TEXT,
            allowNull: false,
            validate: notEmptyMsg("Recipient"),
        },
        items: {
            type: DataTypes.JSON,
            allowNull: false,
            validate: { isArrayOfItems: validateItemsArray },
        },
        status: {
            type: DataTypes.ENUM("Draft", "Issued", "Paid", "Part Paid", "Cancelled", "Disputed", "On Hold"),
            allowNull: false,
            validate: {
                isIn: {
                    args: [["Draft", "Issued", "Paid", "Part Paid", "Cancelled", "Disputed", "On Hold"]],
                    msg: "Invalid status",
                },
            },
        },
        footnotes: {
            type: DataTypes.TEXT,
            allowNull: true,
            validate: {
                isString(value) {
                    if (typeof value !== "string") {
                        throw new Error("Footnotes must be a string");
                    }
                },
            },
        },
        organizationId: {
            type: DataTypes.INTEGER,
            allowNull: false,
            references: { model: "organizations", key: "id" },
        },
        // Virtual field calculating total
        total: {
            type: DataTypes.VIRTUAL,
            get() {
                return parseFloat(
                    this.items
                        .reduce((acc, item) => acc + item.quantity * item.unitPrice * (1 + item.taxRate), 0)
                        .toFixed(2)
                );
            },
        },
        // Virtual field calculating subtotal
        subtotal: {
            type: DataTypes.VIRTUAL,
            get() {
                return this.items.reduce((acc, item) => acc + item.quantity * item.unitPrice, 0);
            },
        },
    });

更新字段时,我遇到了虚拟字段的奇怪问题。

以下测试通过:

    test("Update an invoice", async () => {
        const invoiceData = createInvoiceData();
        const invoice = await Invoice.create(invoiceData);

        await invoice.update({ recipient: "Lorem" });

        expect(invoice.recipient).toBe("Lorem");
    });

但这会引发错误:

    test("Update an invoice", async () => {
        const invoiceData = createInvoiceData();
        const invoice = await Invoice.create(invoiceData);

        await Invoice.update({ recipient: "Lorem" }, { where: { id: invoice.id } });
        const updatedInvoice = await Invoice.findByPk(invoice.id);

        expect(updatedInvoice.recipient).toBe("Lorem");
    });

这是错误:

  ● Invoice Model › Update an invoice

    TypeError: Cannot read properties of undefined (reading 'reduce')

      129 |                 return parseFloat(
      130 |                     this.items
    > 131 |                         .reduce((acc, item) => acc + item.quantity * item.unitPrice * (1 + item.taxRate), 0)
          |                          ^
      132 |                         .toFixed(2)
      133 |                 );
      134 |             },

      at model.reduce (src/models/invoice.js:131:8)
      at model.get (node_modules/sequelize/src/model.js:3651:41)
      at model.get (node_modules/sequelize/src/model.js:3685:33)
      at Function.update (node_modules/sequelize/src/model.js:3247:44)
      at Object.update (tests/invoice.model.test.js:72:17)

显然,在这种情况下,当尝试计算虚拟字段“总计”时,项目是“未定义”的

我不明白为什么第二种编写测试的方法失败了。我正在更新数据库,不是吗?

更奇怪的是,在测试中失败的相同方法在生产代码中似乎运行良好。这就是我在快速路线中所做的:

exports.updateInvoice = async (req, res, next) => { try { const [updateCount] = await Invoice.update( { ...req.body }, { where: { id: req.params.id }, } );
并且工作没有问题。

sequelize.js
1个回答
0
投票
您可以尝试以下方法吗?

test("Update an invoice", async () => { const invoiceData = createInvoiceData(); const invoice = await Invoice.create(invoiceData); await Invoice.update( { recipient: "Lorem" }, { where: { id: invoice.id }, include: [Invoice.associations.items] } ); const updatedInvoice = await Invoice.findByPk(invoice.id); expect(updatedInvoice.recipient).toBe("Lorem"); });
尝试一下并告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.