Angular ng-class 呈现正确 class 但 Karma 显示错误

Angular ng-class renders correct class but Karma shows ERROR

我试图超越书中给出的示例 AngularJS - Up and 运行,并在 HTML 中呈现结果。原始代码可以在这里找到:Book example (controller.js and controllerSpec.js

问题是,如果我使用此代码,Karma 会显示成功,但 HTML 中的 classes 不会按预期呈现(所有帖子都显示为 class“ .read",就好像两者都是 "read = true;"):

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
};

它加载了正确的 classes,但 Karma 显示有错误。像这样:

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();
  });

});

出了什么问题?

那是因为您将 post 作为 {title: 'Last post', read: false} 传递。这让你的 return 重视第二个:

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

因为这个

expect(actualClass.read).toBeFalsy();

显然会失败,因为 actualClass.read 是一个对象。相同于:

expect(actualClass.pending).toBeTruthy();

因为 actualClass.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();
});