1

Я пытаюсь выйти за рамки примера, приведенного в книге AngularJS - Up and Running, и рендеринга результатов в HTML. Исходный код можно найти здесь: Book example (controller.js and controllerSpec.jsУгловой ng-класс делает правильный класс, но показывает карму ОШИБКА

Проблема в том, что если я использую этот код, Karma показывает SUCCESS, но классы в HTML не отображаются как ожидалось (все сообщения отображаются с классом «.read», as если оба были «чтение = истина»):

angular.module('blogApp', []) 
    .controller('MainCtrl', [function() { 
     var self = this; 
     self.items = [ 
      {title: 'First post', read: false}, 
      {title: 'Last post', read: true} 
     ]; 

     self.getPostClass = function(status) { 
      return { 
       read: status.read, 
       pending: !status.read 
      }; 
     }; 
}]); 

нО, если я изменю возвращающиеся значения этого:

return { 
    read: status, 
    pending: !status 
}; 

Он загружает правильные классы, но Карма показывает, что есть ошибки. Как это:

Chromium 39.0.2171 (Ubuntu) Controller: MainCtrl should have highlight items based on state FAILED 
Expected { title: 'Last post', read: false } to be falsy. 
    at Object.<anonymous> (/home/estevan/teste/js/scriptSpec.js:28:30) 
Expected false to be truthy. 
    at Object.<anonymous> (/home/estevan/teste/js/scriptSpec.js:29:33) Chromium 39.0.2171 (Ubuntu): Executed 2 of 2 (1 FAILED) (0.023 secs/0.021 secs) 

Это HTML:

<!DOCTYPE html> 
<html lang="en" ng-app="blogApp"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Blog App</title> 
    <link rel="stylesheet" href="css/main.css"> 
</head> 
<body ng-controller="MainCtrl as ctrl"> 

    <div ng-repeat="post in ctrl.posts" 
     ng-class="ctrl.getPostClass(post.read)"> 
    <h1>{{post.title}}</h1> 
    <!-- It used to have an author --> 
    <p ng-show="post.author" 
     ng-bind="post.author"> 
    </p> 
    </div> 

    <script src="js/angular.min.js"></script> 
    <script src="js/script.js"></script> 
</body> 
</html> 

Это испытание (scriptSpec.js):

describe('Controller: MainCtrl', function() { 
    // Instantiate a new version o my module before each test 
    beforeEach(module('blogApp')); 

    var ctrl; 

    // Before each unit test, instantiate a new instance of the controller 
    beforeEach(inject(function($controller) { 
    ctrl = $controller('MainCtrl'); 
    })); 

    it('should have items available on load', function() { 
    expect(ctrl.posts).toEqual([ 
     {title: 'First post', read: false}, 
     {title: 'Last post', read: true} 
    ]); 
    }); 

    it('should have highlight items based on state', function() { 
    var post = {title: 'Last post', read: true}; 

    var actualClass = ctrl.getPostClass(post); 
    expect(actualClass.read).toBeTruthy(); 
    expect(actualClass.pending).toBeFalsy(); 

    post.read = false; 
    actualClass = ctrl.getPostClass(post); 
    expect(actualClass.read).toBeFalsy(); 
    expect(actualClass.pending).toBeTruthy(); 
    }); 

}); 

Что происходит не так?

ответ

0

Это потому, что вы проходите в своем сообщении как {title: 'Last post', read: false}. Что делает ваше возвращенное значение этого для второго:

actualClass = { 
    read: {title: 'Last post', read: false}, 
    pending: false 
} 

Из-за этого

expect(actualClass.read).toBeFalsy(); 

будет, очевидно, не в состоянии, как actualClass.read является объектом. То же самое с:

expect(actualClass.pending).toBeTruthy(); 

Как фактическийClass.pending является ложным.

Чтобы увидеть, что я имею в виду, падение в лог консоли после каждого actualClass = примерно так:

it('should have highlight items based on state', function() { 
    var post = {title: 'Last post', read: true}; 

    var actualClass = ctrl.getPostClass(post); 
    console.log(actualClass); 
    expect(actualClass.read).toBeTruthy(); 
    expect(actualClass.pending).toBeFalsy(); 

    post.read = false; 
    actualClass = ctrl.getPostClass(post); 
    console.log(actualClass); 
    expect(actualClass.read).toBeFalsy(); 
    expect(actualClass.pending).toBeTruthy(); 
});