gpt4 book ai didi

javascript - angularjs 单元测试 Controller orderBy

转载 作者:行者123 更新时间:2023-11-30 10:25:30 25 4
gpt4 key购买 nike

我在为我的 Controller 编写单元测试时遇到问题,该单元测试用元素测试表中的 orderBy。

我有 advert.html:

<body ng-app="motoAdsApp" ng-controller="AdvertsController">

<form>
<label>Sort by</label>
<select ng-model="sortByCol" ng-options="s.name for s in sortByCols">
<option value=""></option>
</select>
</form>

<br/>

<table border="1">
<tr ng-repeat="advert in adverts| orderBy:sortByCol.key">
<td>
<span>{{advert.countryName}}, {{advert.regionName}}</span>
</td>
<td>{{advert.brandName}}</td>
<td>{{advert.modelName}}</td>
<td>{{advert.year}}</td>
<td>{{advert.price}}</td>
</tr>
</table>

</body>

controllers.js:

var motoAdsApp = angular.module('motoAdsApp', []);

motoAdsApp.controller('AdvertsController', ['$scope', function($scope) {

$scope.sortByCols = [{
"key": "year",
"name": "Year"
}, {
"key": "price",
"name": "Price"
}];

$scope.adverts = [];
var allAdverts = ADVERTS_RESPONSE;

$scope.filter = {
brandName: null,
modelName: null,
country: null,
region: null,
yearFrom: null,
yearTo: null
};

$scope.$watch('filter', filterAdverts, true);

function filterAdverts() {
$scope.adverts = [];
angular.forEach(allAdverts, function(row) {
if (!$scope.filter.country) {
$scope.filter.region = null;
}
if ($scope.filter.brandName && $scope.filter.brandName !== row.brandName) {
return;
}
// ...
$scope.adverts.push(row);
});
}

}
]);

我的单元测试 controllersSpec.js:

describe('MotoAds controllers', function() {

beforeEach(function() {
this.addMatchers({
toEqualData: function(expected) {
return angular.equals(this.actual, expected);
}
});
});

beforeEach(module('motoAdsApp'));

describe('AdvertsController', function() {
var scope, ctrl, $httpBackend;

beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('data/adverts.json').respond(ADVERTS_RESPONSE);

scope = $rootScope.$new();
ctrl = $controller('AdvertsController', {$scope: scope});
}));

it('should sort by year', function() {
$httpBackend.flush();

scope.$apply(function() {
scope.sortByCol = { key: "year"};
});

var prevYear = 0;
for (var i = 0; i < scope.adverts.length; i++) {
var advert = scope.adverts[i];
expect(advert.year).toBeGreaterThan(prevYear);
prevYear = advert.year;
}
});

});

});

运行我的测试后我有这个:

Chrome 30.0.1599 (Windows Vista) MotoAds controllers AdvertsController should so
rt by year FAILED
Expected 2010 to be greater than 2011.
Error: Expected 2010 to be greater than 2011.
at null.<anonymous> (D:/projects/motoads/test/unit/controllers
Spec.js:147:29)
Expected 2009 to be greater than 2012.
Error: Expected 2009 to be greater than 2012.

我认为元素(广告)没有排序。为什么?我该怎么办?

Plunker example (without runnable test)

最佳答案

orderBy 过滤器在像 ng-repeat 这样的元素上使用时,实际上不会对它过滤的数组对象进行排序。数组对象保持不变,但编译器用于创建所有 html 的输出数组已修改。

所以你的 $scope.adverts 数组永远不会改变。它输出到 View 的方式发生了变化,但数组本身没有变化。

单元测试的这一部分看起来更像是您将使用 E2E 测试进行测试的内容。 Controller 并不真正关心元素如何显示。这更多是对观点的责任。 Controller 只关心数据是否从 API 中获取,然后传递给 View 。然后 e2e 测试实际上可以扫描 View 并确保元素被正确排序。

更新:

如果您想在测试中调用 orderBy 过滤器,您可以使用类似于以下的内容来实现:

...
var scope, ctrl, $httpBackend, orderByFilter;
beforeEach(inject(function(_$httpBackend_, $rootScope, $controller, $filter) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('data/adverts.json').respond(ADVERTS_RESPONSE);
orderByFilter = $filter('orderBy');
scope = $rootScope.$new();
ctrl = $controller('AdvertsController', {$scope: scope});
}));
...
it('should do something', function(){
var sortedArray = orderByFilter(scope.adverts, scope.sortByCol.key);
// do something with the sorted array here
});
...

找到了有关如何从 javascript 访问 orderBy 过滤器的文档 here

希望对您有所帮助。

关于javascript - angularjs 单元测试 Controller orderBy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19776573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com