Angularjs 单元测试控制器 orderBy.
angularjs unit test controller orderBy
我在为我的控制器编写单元测试时遇到问题,该单元测试在带有元素的表中按顺序进行测试。
我有广告.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>
控制器.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);
});
}
}
]);
我的单元测试控制器规格.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示例(无可运行测试)
orderBy
过滤器在像 ng-repeat
这样的元素上使用时,实际上并不对它过滤的数组对象进行排序。 数组对象保持不变,但编译器用于创建所有 html 的输出数组被修改。
因此,您的$scope.adverts
阵列永远不会改变。 它输出到视图的方式会改变,但数组本身不会改变。
单元测试的这一部分看起来更像是使用 E2E 测试进行测试的内容。 控制器并不真正关心元素的显示方式。 这更多的是对观点的责任。 控制器只关注是否从 API 中获取数据,然后传递给视图。 然后 e2e 测试实际上可以扫描视图并确保元素正确排序。
更新:
如果要在测试中调用 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
过滤器的文档可在此处找到
希望有帮助。
相关文章:
- 在指令控制器中使用$attrs时出现问题
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 从控制器返回后Ajax启动事件激发
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- 如何在单击复选框后调用控制器方法
- 在控制器和数据对象之间同步数据
- 将Javascript数组发送到控制器ASP.NET MVC
- 角度控制器结构
- 如何在Jquery中发布后将值从视图返回到控制器
- 将值从html传递到AngularJS控制器
- 从我的控制器返回一个不同于200的代码以触发ajax错误,这被认为是一种好的做法吗
- 从控制器继承了隔离的作用域以生成可重用的指令
- Flash Uploadify在调用我的MVC控制器时没有保留会话/授权
- 为什么不't我的变量在我的控制器中填充后在我的视图中呈现
- Nodejs API控制器,用于在API之间切换
- 对具有ui typeahead的对象中的值执行orderBy
- 如何在Angular单元测试中从另一个控制器的rootScope将方法添加到rootScope中
- 将不在模型中的数据返回到mvc控制器
- Angularjs 单元测试控制器 orderBy.
- angular将控制器函数重新用作自定义orderBy函数