使用Kendo Grid/Datasource的单元测试Angular Controller
Unit testing Angular Controller that uses Kendo Grid/Datasource
我的项目使用AngularJS+Kendo UI。我正在尝试测试我的一个使用剑道UI网格的控制器:
angular.module('myApp')('DevicesCtrl', function ($scope) {
$scope.gridOptions = {
dataSource: {
transport: {
read: {
url: "/devices",
dataType: "json"
}
},
change: function(){
var view = this.view();
$scope.devices = [];
$.each(view, function(i, v) {
$scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"});
});
$scope.$apply();
}
},
columns: [
{
field: "name",
title: "Name",
width: 250,
template: function (item) {
var itemStatus = item.status == 0 ? 'failure' : 'success';
return '<div label size="small" operation="' + itemStatus + '" label="' + item.name + '"></div>';
}
},
{
field: "status",
title: "Status"
}
]
};
});
当我编写单元测试时,我预计会调用一个GET请求:
describe('deviceCtrl', function () {
var scope, deviceCtrl, httpBackend, timeout;
beforeEach(module("myApp"));
beforeEach(module('src/modules/devices/views/device.html'));
beforeEach(inject(function ($controller, $rootScope, $httpBackend, $timeout, $state) {
scope = $rootScope.$new();
httpBackend = $httpBackend;
timeout = $timeout;
httpBackend.expectGET('languages/en_US.json').respond({});
deviceCtrl = $controller("DeviceCtrl", {
$scope: scope
});
$state.go("devices");
timeout.flush()
}));
it('should load the switch list', function () {
httpBackend.expectGET("/devices").respond(
[{"id":"1","name":"name 1","status":"1"},
{"id":"2","name":"name 2","status":"2"}]
);
httpBackend.flush();
});
});
但这种期望从未得到满足,也没有提出任何要求。所以我的问题是:有没有办法让Kendo Grid/Datasource进行这个调用,这样我就可以嘲笑它了?
我看到了一些关于如何使用Mockjax的示例(http://www.telerik.com/forums/best-practice-mocking-with-datasource)但我更喜欢使用角度库来做到这一点。
经过大量研究,我可以找到一些方法来测试使用Kendo数据源的控制器。
Kendo有自己的方法来调用Ajax来获取数据,并且不使用常规的Angular$http来实现这一点,所以使用Angular工具(Angular mock)进行测试有点棘手。让我们进入选项:
1–使用常规的Angular方式进行Ajax调用
Kendo让我们改变它获取数据的方式,所以不用这么做:
dataSource: new kendo.data.DataSource({
transport: {
read: {
url: "/devices,
dataType: "json"
}
},
change: function(){
var view = this.view();
$scope.devices = [];
$.each(view, function(i, v) {
$scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"});
});
$scope.$apply();
}
});
我们将改为:
dataSource: new kendo.data.DataSource({
transport: {
read: function(options){
$http.get("/devices").then(function(response){
options.success(response.data);
$scope.devices = [];
response.data.forEach(function(v){
$scope.devices.push({id: v.id, description: v.name, status: v.status == 0 ? "failure" : "success"});
});
});
}
}
});
然后我们可以使用常规的$httpBackend.expectGET(url)来模拟Ajax调用。我个人喜欢这种方法,因为我们有更多的控制权。Ps.:使用函数内部的变量"options",我们可以访问Grid过滤器、排序和分页值。
2–模仿剑道Ajax呼叫
通过这种方式,我们在Controller上几乎没有任何更改,唯一需要更改的是使用新的kendo.data.Datasource({})创建一个新的数据源,而不仅仅是传递选项。这是需要的,因为我们在测试用例中调用了read函数。我尝试了不同的方法来模拟这个Ajax请求,但唯一能让它工作的方法是使用一个名为Jasmine Ajax的工具。在测试用例中,我们会写一些类似的东西:
var request = jasmine.Ajax.requests.mostRecent();
request.response(MockData);
我希望这能帮助其他人。
- 如何在Angular单元测试中从另一个控制器的rootScope将方法添加到rootScope中
- Angular 2和服务单元测试
- 用于单元测试的模拟Angular引导程序ui指令
- 单元测试Angular自举代码
- Angular ui路由器单元测试(状态为url)
- 如何在Angular 2中对指令进行单元测试2
- Angular js单元测试模拟文档
- angular单元测试http请求问题
- 如何在单元测试中注入Angular控制器
- CSS选择器在Angular单元测试w/karma&柴
- Karma 单元测试 Angular JS 指令与 externalUrl
- 单元测试Angular+Browserify+Gulp和Jasmine
- 使用Kendo Grid/Datasource的单元测试Angular Controller
- 如何在指令link函数中单元测试Angular的routechangessuccess
- 单元测试angular引导模态服务
- 单元测试Angular + Protractor
- 单元测试Angular HTTP拦截器
- 单元测试angular指令
- 单元测试Angular with Breeze
- 单元测试Angular指令