当前位置: 首页 > 知识库问答 >
问题:

如何窥探动态调用的函数

闻安宜
2023-03-14

我正在与Javascript、Mocha、Chai和SinonJ合作。我想做的是监视一个“equals”方法,该方法由另一个方法“compareUsingOperator”动态调用。下面的代码显示了我的类“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”方法的调用。这也是我的问题。我想知道是否调用了“equals”。我使用以下断言:

assert.called(actual.equals);

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

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

预期行为应为绿色测试。

我的单元测试有什么问题?在控制台的帮助下.log我可以证明“等于”已经被调用了。

问候

弗洛里安

共有1个答案

温成济
2023-03-14

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

   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",
        };
    }

现在该类是可测试的。

坦克和问候

弗洛里安

 类似资料:
  • 问题内容: 我有以下代码: 我怎么能叫和动态? 例如: 我使用了大括号,因为这是我以前在PHP中使用的方式,但是显然不起作用。 如何使用Python做到这一点? 问题答案: 如果不想使用并且不想创建单独的模块和/或类来封装要动态调用的函数,则可以将它们作为当前模块的属性来调用:

  • 问题内容: 我有一个字符串数组,其中包含类中方法的名称 在课堂上,我正在创建一个实例(例如)。现在,我可以调用,只是我想循环读取String数组。这可能吗? 问题答案: 您可以使用反射。通过调用完成 您必须处理大量异常,并且您的方法必须为。需要注意的是Java编码惯例喜欢到。 但是,使用反射应该是最后的选择。您应该使用更多的面向对象技术。 如果您经常需要类似的功能,也许您可​​以看看在Java平台

  • 调用回调函数,并把一个数组参数作为回调函数的参数。 local args = {...} or {} method_name(unpack(args, 1, table.maxn(args))) 使用场景 如果你的实参 table 中确定没有 nil 空洞,则可以简化为 method_name(unpack(args)) 你要调用的函数参数是未知的; 函数的实际参数的类型和数目也都是未知的。 伪代

  • 我使用的是Mockito1.9.0。我想在JUnit测试中模拟类的单个方法的行为,因此 问题是,在第二行中,实际上是被调用的,导致了一个异常。我使用模拟的唯一原因是,以后每当调用时,将不会调用真正的方法,而返回对象。 是接口,是接口的实现(如果这很重要的话)。 我需要做些什么来纠正这种间谍行为?

  • 问题内容: 我正在寻找一个窍门。我知道如何在JavaScript中调用动态的任意函数,并传递特定的参数,如下所示: 我知道如何使用内部的集合传递可选的,无限制的参数,但是,我不知道如何发送任意数量的参数以动态发送给它;我该如何完成这样的工作,但是要有任意数量的可选参数(不要使用丑陋的– )? 问题答案: 使用函数的apply方法:- 编辑 :在我看来,这将是一个稍微的调整会更有用: 这将在浏览器之

  • 我一直在做这把小提琴: https://jsfidle.net/j1vrb7to/165/ 那把小提琴的密码是这样的: HTML: JavaScript: 当用户在文本框中输入值时,我想更新另一个字段的值以显示正在运行的总计。最终,我将需要在我的表单上跟踪20+运行总数。不需要维护20+个函数,是否可以使用单个函数动态计算运行总数?下面是一些伪代码来演示我的想法: