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();
});
我试图超越书中给出的示例 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();
});