计算出的强制淘汰赛在更换可观察到的内部后重新评估

时间:2018-11-06 10:39:31

标签: javascript knockout.js knockout-3.0

一个同事遇到了一个问题,他要测试的计算机没有返回预期的输出。发生这种情况是因为我们想存根其他计算对象(它们又依赖于其他计算对象)。存根后,计算中剩下0个可观察值,并且计算中不断返回缓存的结果。

我们如何强制计算重新评估其中不再具有原始可观测量的计算量?

ComboBox
let arrayWithUnique1DArray = [[4,6,4],[4,9,9]].map((item)=>{ 
  return [...(new Set(item))] 
});
console.log(arrayWithUnique1DArray)

1 个答案:

答案 0 :(得分:3)

我能想到的唯一解决方案不涉及更改ViewModel的代码,而是先存根ko.computed ...

在下面的示例中,我将ko.computed替换为扩展版本。该扩展公开了一个属性.stub,该属性使您可以编写自定义函数。设置此功能后,计算所得的值将使用提供的逻辑进行重新计算。

在测试文件中,您需要能够在实例化ViewModel实例之前 替换准备代码中对ko.computed的全局引用。

// Extender that allows us to change a computed's main value getter
// method *after* creation
ko.extenders.canBeStubbed = (target, value) => {
  if (!value) return target;
  
  const stub = ko.observable(null);
  const comp =  ko.pureComputed(() => {
    const fn = stub();
    
    return fn ? fn() : target();
  });
  
  comp.stub = stub;
  
  return comp;
}

// Mess with the default to ensure we always extend
const { computed } = ko;
ko.computed = (...args) => 
  computed(...args).extend({ canBeStubbed: true });

// Create the view model with changed computed refs
const ViewModel = function() {
  this.otherComputed = ko.computed(() => true);
  this.computedUnderTest = ko.computed(() => this.otherComputed());
};

const vm = new ViewModel();

function expect(expected) {
  console.log("Test succeeded:", vm.computedUnderTest() === expected);
}


expect(true);

// Replace the `otherComputed`'s code by another function
vm.otherComputed.stub(() => false);

expect(false);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

在我自己的项目中,我倾向于使用完全不同的方法来测试计算机,该方法侧重于将逻辑与依赖项分离。让我知道上面的示例是否不适合您。 (如果已经满足您的需求,我不会写另一个答案)