【问题标题】:How to spy on dynamically called function如何监视动态调用的函数
【发布时间】:2019-09-11 08:13:19
【问题描述】:

我正在使用 Javascript、Mocha、Chai 和 SinonJs。我想要做的是监视由另一个方法“compareUsingOperator”动态调用的方法“equals”。下面的代码显示了我的类“StringComparator”,它有两个方法“equals”和“compareUsingOperator”。

export default class StringComparator {

    private compareFunctionList: {[key in "=" | "!=" | "<>" | "<" | "<=" | ">" | ">="]: Function};

    public constructor() {
        this.compareFunctionList = {
            "=" : this.equals,
            "!=" : this.notEquals,
            "<>" : this.notEquals,
            "<" : this.lessThan,
            "<=" : this.lessThanOrEquals,
            ">" : this.greaterThan,
            ">=" : this.greaterThanOrEquals,
        };
    }

    public equals(value1: string, value2: string): boolean {
        if (typeof value1 != "string" || typeof value2 != "string") {
            console.log(value1);
            console.log(value2);
            throw new TypeError("Invalid data type!");
        }

        return (value1 === value2);
    }

    public compareUsingOperator(operator: "=" | "!=" | "<>" | "<" | "<=" | ">" | ">=", value1: string, value2: string): boolean {
        if (typeof operator != "string" || typeof value1 != "string" || typeof value2 != "string") {
            throw new TypeError("Invalid data type!");
        }

        if (!Object.keys(this.compareFunctionList).includes(operator)) {
            throw new ReferenceError("Undefined operator!");
        }

        const fn: Function = this.compareFunctionList[operator];
        return fn.call(this, value1, value2);
    }

}

这是我的单元测试:

            describe("compareUsingOperator", () => {
                context("calls", () => {
                    comparator.validOperators.forEach((operator) => {
                        it("the proper function according to the given operator", () => {
                            sinon.spy(actual, "equals");

                            actual.compareUsingOperator("=", comparator.value1, comparator.value2);

                            assert.called(actual.equals);
                            actual.equals.restore();
                        });
                    });

                });
            });

在我的单元测试中,我对“equals”方法设置了一个间谍,如下所示:

sinon.spy(actual, "equals");

“actual”是“StringComparator”的一个实例。

在下一步我打电话给:

actual.compareUsingOperator("=", comparator.value1, comparator.value2);

在这个方法中执行以下代码:

const fn: Function = this.compareFunctionList[operator];
        return fn.call(this, value1, value2);

这是对“equals”方法的调用。这也是我的问题。我想知道是否调用了“等于”。我正在使用以下断言:

assert.called(actual.equals);

我从 chai/sinon 得到的答案是:

AssertError: expected equals to have been called at least once but was never called

预期的行为应该是绿色测试。

我的单元测试有什么问题?在 console.log 的帮助下,我可以证明已经调用了“equals”。

问候

弗洛里安

【问题讨论】:

    标签: mocha.js chai sinon


    【解决方案1】:

    我自己找到了答案。我不得不更换:

       const fn: Function = this.compareFunctionList[operator];
       return fn.call(this, value1, value2);
    

    与:

        const fn: string = this.compareFunctionList[operator];
        return this[fn](value1, value2);
    

    还有这个:

    private compareFunctionList: {[key in "=" | "!=" | "<>" | "<" | "<=" | ">" | ">="]: Function};
    
        public constructor() {
            this.compareFunctionList = {
                "=" : this.equals,
                "!=" : this.notEquals,
                "<>" : this.notEquals,
                "<" : this.lessThan,
                "<=" : this.lessThanOrEquals,
                ">" : this.greaterThan,
                ">=" : this.greaterThanOrEquals,
            };
        }
    

    这样:

    private compareFunctionList: {[key in "=" | "!=" | "<>" | "<" | "<=" | ">" | ">="]: string};
    
        public constructor() {
            this.compareFunctionList = {
                "=" : "equals",
                "!=" : "notEquals",
                "<>" : "notEquals",
                "<" : "lessThan"
                "<=" : "lessThanOrEquals",
                ">" : "greaterThan",
                ">=" : "greaterThanOrEquals",
            };
        }
    

    现在这个类是可测试的。

    坦克和问候

    弗洛里安

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 2017-10-20
      • 2018-12-30
      • 1970-01-01
      • 2019-10-07
      相关资源
      最近更新 更多