【问题标题】:Sinon.spy not working on simple objectSinon.spy 不适用于简单对象
【发布时间】:2018-06-21 01:49:31
【问题描述】:

背景

我正在尝试测试一个名为 multiQuery 的函数,并确保它以正确的参数和正确的次数调用另一个函数 query

代码

以下是我正在使用的代码的简化。这是我用来创建对象的对象:

const createDb = () => {

    const query = (sql, values, type = "all") => {
        console.log(`original query called: ${sql}, ${values}, ${type}`);
        return Promise.resolve();
    };

    const multiQuery = requests => Promise.all(
        requests.map( req => query(req.sql, req.values, req.mode || "all") )
    );

    return {
        query,
        multiQuery
    };
};

这是测试:

const sinon = require("sinon");
const chai = require("chai");
const expect = chai.expect;
const sinonChai = require("sinon-chai");
chai.use(sinonChai);

describe("multiQuery", () => {

        it("should call query multiple times with the correct parameters", async() => {
            const requests = [
                { sql: "hello", values: [1, 2, 3],  mode: "first"   },
                { sql: "world", values: [4, 5, 6],  mode: "all"     },
                { sql: "moon",  values: [7, 8]  }
            ];

            const db = createDb();
            const spy = sinon.spy( db, "query" );

            await db.multiQuery( requests );

            expect( spy ).to.have.been.calledThrice();
            expect( spy ).to.have.been.calledWith( "hello", [1, 2, 3], "first" );
        });
});

问题

问题是,无论我做什么,我总是得到消息:

AssertionError:预期的查询已经被调用了三次,但是 它被调用了 0 次

而且我无法修复它。

这是因为multiQuery 绑定到原始函数而不是间谍。

头脑风暴

我正在考虑可能在multiQuery 中注入query 依赖项,但是我不想每次调用它时都传递一个依赖项,也不想用不需要的工厂方法污染对象的API .

我真的不知道如何在这里解决这个问题...... 我该如何解决这个问题?

【问题讨论】:

    标签: javascript node.js unit-testing mocking sinon


    【解决方案1】:

    您对测试失败的原因是正确的。

    您需要通过将 query 放在对象上,使 multiQuery 引用与返回的 query 相同:


    一个潜在的解决方案:

    const createDb = () => {
       const db = { //the name here isn't important
            query,
            multiQuery
        };
    
        const query = (sql, values, type = "all") => {
            console.log(`original query called: ${sql}, ${values}, ${type}`);
            return Promise.resolve();
        };
    
        const multiQuery = requests => Promise.all(
            requests.map( req => db.query(req.sql, req.values, req.mode || "all") )
        );
    
        return db;
    };
    

    【讨论】:

      【解决方案2】:

      四处打听并进行更多测试后,我发现如果我将createDb函数更改为以下内容:

      const createDb = () => {
          const db = {}
          db.query = (sql, values, type = "all") => {
              console.log(`original query called: ${sql}, ${values}, ${type}`);
              return Promise.resolve();
          };
          db.multiQuery = requests => Promise.all(
              requests.map( req => db.query(req.sql, req.values, req.mode || "all") )
          );
      
          return db;
      }
      

      sinon 中的 spy 方法将按预期工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-17
        • 1970-01-01
        • 2021-04-22
        • 2018-01-24
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 2021-04-28
        相关资源
        最近更新 更多