Search code examples
javascriptunit-testingknockout.jsqunit

Knockout computed doesn't seem to be updating


I have a simple view-model that I'm unit-testing and I can't seem to fathom the behaviour. I figured it might be something to do with knockout selectively tracking dependencies or caching computed results.

The code (represented in this fiddle):

function viewModel() {
 var serviceErrors = ko.observable([]),
     isCancelImmediately = ko.observable(true),
     futureDate = ko.observable(),
     errors = ko.computed(function() {
         var allErrors = serviceErrors(),
             isImmediate = isCancelImmediately(),
             selectedDate = futureDate();

         if(!selectedDate && !isImmediate) {
          allErrors.push('Please select a date if not immediate.');   
         }

         return allErrors;
     });

    return {
        futureDate: futureDate,
        errors: errors,
        isCancelImmediately: isCancelImmediately
    };
}
test('should give error if user has not selected a date when closing immediately', function() { 
    var sut = viewModel();

    ok(!sut.futureDate(), 'no date should be set to start with');    
    sut.isCancelImmediately(false);
    equal(sut.errors().length, 1, 'should contain a future date error if user hasn\'t entered a date');
    sut.futureDate('11/12/2014');
    equal(sut.futureDate(), '11/12/2014', 'should have set future date');
    equal(sut.errors().length, 0, 'should not be showing error');
});

Can someone tell me why the last assertion's failing?


Solution

  • I think that:

    allErrors.push('Please select a date if not immediate.'); 
    

    Is actually pushing a string to the array that your serviceErrors observable is containing. So you are also pushing to serviceErrors when you run push on addErrors.