2013-03-27 8 views
0

Я пытаюсь написать тест для поля ko.computed, который зависит от двух других сложных вычислений (удаленных здесь для демонстрации).Измельчение вычисляемых полей с помощью Jasmine и Knockout

function PositionsViewModel(options) { 
    var self = this; 
    self.computed1 = ko.computed(function() { return 1; }); 
    self.computed2 = ko.computed(function() { return 2; }); 
    self.computedIWantToTest = ko.computed(function() { 
    return self.computed1() + self.computed2(); 
    }); 
} 

В моем тесте жасмин я создаю экземпляр виртуальной машины в beforeEach так:

this.subject = new PositionsViewModel(); 

Я хочу, чтобы иметь возможность окурок computed1 и computed2, чтобы я мог проверить computedIWantToTest в изоляции. Пока мои попытки сделать это потерпели неудачу.

Я пробовал прямо на экземпляре vm. Но, похоже, что, хотя методы перезаписаны, вычисляемые кешируют функцию в некотором роде.

+0

Вы правильны, 'computed' действительно держит ссылку на наблюдаемые (в том числе computeds), когда он первый бежит, чтобы установить его отслеживание зависимостей. Вам нужно будет изменить исходные вычисления, не создавая для них новую функцию. – Tyrsius

ответ

0

Одним из способов было бы ввести первые две вычислимые функции.

http://jsfiddle.net/kevincollins/RwKAD/

var PositionsViewModel = function (computedService1, computedService2, options) { 

    this.defaultComputed1 = ko.computed(function() { return 1; }); 
    this.defaultComputed2 = ko.computed(function() { return 2; }); 

    this.computed1 = computedService1 || this.defaultComputed1; 
    this.computed2 = computedService2 || this.defaultComputed2; 

    var self = this; 
    this.computedIWantToTest = ko.computed(function() { 
    return self.computed1() + self.computed2(); 
    }); 

}; 

var vm1 = new PositionsViewModel(); 
ko.applyBindings(vm1, document.getElementById("o1")); 

var ComputedServiceMock1 = ko.computed(function() { return 100; }); 
var ComputedServiceMock2 = ko.computed(function() { return 200; });  

var vm2 = new PositionsViewModel(ComputedServiceMock1, ComputedServiceMock2); 
ko.applyBindings(vm2, document.getElementById("o2")); 
+1

Он работает, но мне нужно изменить код приложения для тестирования. Я думаю, что это определенно меньше идеала. – iterion

+1

Это неправильный подход. Использование инъекции зависимостей может стать громоздким на чем-то крупном очень быстро. Нам нужен способ заставить вычисляемое значение обновляться против функции, которая будет проверяться (и заменена). – genexp