You need to enable JavaScript to run this app. JS策略模式实现中Jest报this.stragtegy.doOperation方法错误
优惠活动
大模型
产品
解决方案
定价
更多

JS策略模式实现中Jest报this.stragtegy.doOperation方法错误

报错根因定位

报错是两类问题叠加导致的,其中直接触发错误的原因是接口不匹配:

  • 核心方法名完全不匹配:Calculation类的doOperation方法内部,尝试调用当前绑定策略实例的doOperation方法,但两个策略类(CalculationStrategy、CalculationStrategyB)对外实现的方法名是doAction,实例上不存在doOperation方法,自然会抛出this.strategy.doOperation is not a function的错误。
  • 拼写不一致导致的逻辑失效:全链路代码中对策略属性的拼写存在错误(错拼为stragtegy,正确拼写为strategy):
    • Calculation类的构造函数中初始化的实例属性是错拼的this.stragtegy
    • 类中定义的setter访问器键名是正确的strategy(只有给实例的strategy属性赋值时才会触发setter逻辑)
    • 测试用例中直接给实例的错拼属性stragtegy赋值,完全没有触发预先定义的setter逻辑,虽然碰巧同名能拿到值,但设计逻辑已经完全走偏
  • 策略模式核心约定缺失:所有策略类没有遵循统一接口的要求,方法名自定义,和上下文类的调用逻辑没有对齐。
代码调整方案

按照策略模式的规范逐文件修改即可,核心是统一方法名、修正拼写、打通赋值逻辑:

1. 调整Calculation.js

修正所有错拼的属性名,保证内部引用一致:

class Calculation {
    constructor(a, b, op) {
        this.a = a;
        this.b = b;
        this.op = op;
        // 修正拼写
        this.strategy = null;
    }

    static Create(a, b, op){
        return new Calculation(a, b, op);
    }

    GetResults() {
        return this.op(this.a, this.b)
    }

    addOperationToName(fn){
        return function(name){
            const operation = name + ' is an operation';
            return fn(operation);
        }
    }

    sayOperation(name){
        return name;
    }

    obtainStructor(){
        return this.a +' '+ this.b;
    }

    // 修正setter的参数和赋值逻辑
    set strategy(strategyInstance){
        this.strategy = strategyInstance;
    }

    doOperation(){
        // 修正属性引用,调用策略实例的统一方法
        return this.strategy.doOperation();
    }
}
module.exports = Calculation;

2. 调整CalculationStrategy.js

把方法名对齐上下文的调用要求,保证接口统一:

class CalculationStrategy{
    // 方法名从doAction改为doOperation
    doOperation(){
        return 'This is Calculation Strategy 1';
    }
}
module.exports = CalculationStrategy;

3. 调整CalculationStrategyB.js

同样对齐统一的方法名要求:

class CalculationStrategyB{
    // 方法名从doAction改为doOperation
    doOperation(){
        return 'This is Calculation Strategy 2';
    }
}
module.exports = CalculationStrategyB;

4. 调整测试用例CalculationStrategy.test.js

修正赋值时的属性名,保证赋值逻辑能正确触发setter,把策略实例绑定到实例属性上:

const calculation = require('../src/models/Calculation');
const calculationStrategy = require('../src/CalculationStrategy');
const calculationStrategyB = require('../src/CalculationStrategyB');
const Product = require('../src/Operations/Product');

test('Test Strategy of Calculation', () => {
    let op = Product;
    let customCalculation = new calculation(1,2, op);
    const strategy = new calculationStrategy();
    const strategyB = new calculationStrategyB();
    // 修正属性名,从错拼的stragtegy改为正确的strategy
    customCalculation.strategy = strategy;
    expect(customCalculation.doOperation()).toBe('This is Calculation Strategy 1');
    customCalculation.strategy = strategyB;
    expect(customCalculation.doOperation()).toBe('This is Calculation Strategy 2');
});

修改完成后,Jest测试即可正常运行,完全符合策略模式的核心逻辑:上下文类负责持有策略实例、委托策略执行具体逻辑,所有策略类实现统一接口,可以灵活替换且不需要修改上下文代码。

内容的提问来源于stack exchange,提问作者BeefNoodle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 22:45:04