为 angular REST 应用编写测试
Write tests for an angular REST app
到目前为止我一直一无所知。假设我有这个非常简单的应用程序模块:
var app = angular.module('myApp', []);
app.service('searchService', ['$http', function($http){
var baseURL="https://someonehost.com/product/search&query=";
return {
search: function(query){
return $http.get(baseURL+query);
}
};
}]);
app.controller('mainCtrl', ['$scope','searchService',function($scope, searchService) {
searchService.search($scope.searchWords).success(function(data) {
$scope.responseData=data;
});
}]);
它适用于浏览器。现在我尝试使用 karma、mocha 和 chai 对其进行测试。假设我想写一个测试用例来测试请求的成功路径。我应该怎么写呢?到目前为止,这是我正在尝试的:
describe('',function(){
var $httpBackend = null;
var locationService = null;
var baseURL="https://someonehost.com/product/search&query=";
beforeEach(function(){
module('myApp');
inject(function(_$httpBackend_,_locationService_){
$httpBackend = _$httpBackend_;
locationService = _locationService_;
});
});
it('test case 1',function(){
var searchWord = 'car';
$httpBackend.when('GET',baseURL+searchWord).respond(200,'');
$httpBackend.expectGET(baseURL+searchWord);
searchService.search(searchWord).success(function(data) {
console.log('data: '+data);
});
$httpBackend.flush();
});
});
但是它 returns 没有数据,它应该在控制台中:
LOG: 'data: '
Firefox 37.0.0 (Ubuntu): Executed 1 of 1 SUCCESS (0.033 secs / 0.006 secs)
默认情况下,Angular 在单元测试期间不接受外部服务的 $http。您应该为假数据提供模拟并且只测试代码的完整性。
您要做的不是单元测试而是集成测试,几周前我遇到了完全相同的问题。我发现这个文件覆盖了 ngMocks 并执行了正常的查询。
https://gist.github.com/kyro38/3371aaac54bf6583852f
在您的 Karma/Mocha/WhatEver 测试配置中,您在 angular 之后导入它(下面的示例是针对 Karma 的):
// Karma configuration
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './',
// frameworks to use
// some available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'chai'],
// list of files / patterns to load in the browser
files: [
'./bower_components/jquery/dist/jquery.js',
'./bower_components/angular/angular.js',
'./src/client/test-helpers/angular-mocks-with-real-backend.js', [...]
然后你就可以运行你想要的测试了。如果有任何问题,请告诉我。
不要忘记让你的测试异步 ;)
https://jasmine.github.io/edge/introduction.html#section-Asynchronous_Support
小心 $httpBackend
如文档中所述:
Fake HTTP backend implementation suitable for unit testing
applications that use the $http service.
尝试改用 $http。
it('should get nok 8 one single contact', function(done) {
var promise = $http({
method: 'get',
url: baseurl + '/contact/list',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': '*/*'
},
params: {
nokid: 8
}
});
promise.then(function(result) {
expect(result.status).toEqual(200);
}, function(error) {
expect(error.status).toEqual(200);
}).
finally(done);
});
https://docs.angularjs.org/api/ngMock/service/$httpBackend#!
最后提示:在您当前的测试中,您给 expectGET 一个错误的 url :
var searchWord = 'car';
$httpBackend.expectGET(searchWord);
我会试试这个
it('test case 1',function(done){
$http({
method: 'get',
url: baseURL + 'car',
...
}).then(function (success) {
console.log('data: ' + success.data);
done(); // stop test from waiting
}, function (fail) {
console.log('data: ' + fail);
done(); // stop test from waiting
});
});
到目前为止我一直一无所知。假设我有这个非常简单的应用程序模块:
var app = angular.module('myApp', []);
app.service('searchService', ['$http', function($http){
var baseURL="https://someonehost.com/product/search&query=";
return {
search: function(query){
return $http.get(baseURL+query);
}
};
}]);
app.controller('mainCtrl', ['$scope','searchService',function($scope, searchService) {
searchService.search($scope.searchWords).success(function(data) {
$scope.responseData=data;
});
}]);
它适用于浏览器。现在我尝试使用 karma、mocha 和 chai 对其进行测试。假设我想写一个测试用例来测试请求的成功路径。我应该怎么写呢?到目前为止,这是我正在尝试的:
describe('',function(){
var $httpBackend = null;
var locationService = null;
var baseURL="https://someonehost.com/product/search&query=";
beforeEach(function(){
module('myApp');
inject(function(_$httpBackend_,_locationService_){
$httpBackend = _$httpBackend_;
locationService = _locationService_;
});
});
it('test case 1',function(){
var searchWord = 'car';
$httpBackend.when('GET',baseURL+searchWord).respond(200,'');
$httpBackend.expectGET(baseURL+searchWord);
searchService.search(searchWord).success(function(data) {
console.log('data: '+data);
});
$httpBackend.flush();
});
});
但是它 returns 没有数据,它应该在控制台中:
LOG: 'data: '
Firefox 37.0.0 (Ubuntu): Executed 1 of 1 SUCCESS (0.033 secs / 0.006 secs)
默认情况下,Angular 在单元测试期间不接受外部服务的 $http。您应该为假数据提供模拟并且只测试代码的完整性。
您要做的不是单元测试而是集成测试,几周前我遇到了完全相同的问题。我发现这个文件覆盖了 ngMocks 并执行了正常的查询。
https://gist.github.com/kyro38/3371aaac54bf6583852f
在您的 Karma/Mocha/WhatEver 测试配置中,您在 angular 之后导入它(下面的示例是针对 Karma 的):
// Karma configuration
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './',
// frameworks to use
// some available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'chai'],
// list of files / patterns to load in the browser
files: [
'./bower_components/jquery/dist/jquery.js',
'./bower_components/angular/angular.js',
'./src/client/test-helpers/angular-mocks-with-real-backend.js', [...]
然后你就可以运行你想要的测试了。如果有任何问题,请告诉我。
不要忘记让你的测试异步 ;)
https://jasmine.github.io/edge/introduction.html#section-Asynchronous_Support
小心 $httpBackend
如文档中所述:
Fake HTTP backend implementation suitable for unit testing applications that use the $http service.
尝试改用 $http。
it('should get nok 8 one single contact', function(done) {
var promise = $http({
method: 'get',
url: baseurl + '/contact/list',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': '*/*'
},
params: {
nokid: 8
}
});
promise.then(function(result) {
expect(result.status).toEqual(200);
}, function(error) {
expect(error.status).toEqual(200);
}).
finally(done);
});
https://docs.angularjs.org/api/ngMock/service/$httpBackend#!
最后提示:在您当前的测试中,您给 expectGET 一个错误的 url :
var searchWord = 'car';
$httpBackend.expectGET(searchWord);
我会试试这个
it('test case 1',function(done){
$http({
method: 'get',
url: baseURL + 'car',
...
}).then(function (success) {
console.log('data: ' + success.data);
done(); // stop test from waiting
}, function (fail) {
console.log('data: ' + fail);
done(); // stop test from waiting
});
});