我在编写我认为应该是简单单元测试的内容时遇到了问题。我有以下 Controller :
(function(){ 'use strict';
var LoginController = function($scope, $state, RestService){
var _user = {};
var _message = 'hello';
var _login = function(username, password){
var _success = function(response){
_message = response.success;
_user = response.user;
};
var _error = function(response){
_message = response.success;
};
RestService.postData('/api/login', {username: username, password: password}, _success, _error, {showLoader: true});
};
$scope.model = {
login: _login,
user: _user,
message: _message
};
};
angular.module('danny').controller('LoginController',['$scope', '$state', 'RestService',LoginController]);
})();
这是规范:
describe('LoginController', function(){
var scope, $httpBackend, controller, restService;
beforeEach(function(){
module('danny');
});
beforeEach(inject(function(_$controller_, _$rootScope_, _$httpBackend_, _RestService_){
$httpBackend = _$httpBackend_;
restService = _RestService_;
scope = _$rootScope_.$new();
controller = _$controller_('LoginController', {
$scope: scope,
RestService: restService
});
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('successfully logging in', function(){
it('should redirect to /blog when authenticated', function(){
var user = {"username":"danny@ravenartmedia.com", "password":"test"};
expect(user.username).toEqual('danny@ravenartmedia.com');
$httpBackend.expectPOST('/api/login', user);
scope.model.login(user);
$httpBackend.flush();
expect(scope.model.user).not.toBe(undefined);
});
});
});
当我运行测试时, karma 输出是这样的:
C:\Program Files (x86)\JetBrains\WebStorm 9.0.1\bin\runnerw.exe" C:\nodejs\node.exe c:\Users\danny_000\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt test
Running "karma:development" (karma) task
INFO [karma]: Karma v0.12.16 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8)]: Connected on socket SWVDLzehlqv2Z3J0C2Av with id 62852294
PhantomJS 1.9.8 (Windows 8): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
PhantomJS 1.9.8 (Windows 8) LoginController successfully logging in should redirect to /blog when authenticated FAILED
SyntaxError: Unable to parse JSON string
at fromJson (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:1066)
at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1646
at $httpBackend (c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1194)
at sendReq (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9616)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9331
at processQueue (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13171)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13187
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14384
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14200
at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1525
at c:/Projects/dannyschreiber/public/src/core/security/login-controller.spec.js:6
Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.3.9/$rootScope/inprog?p0=%24digest
at beginPhase (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14738)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14180
at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1557
at c:/Projects/dannyschreiber/public/src/core/security/login-controller.spec.js:6
PhantomJS 1.9.8 (Windows 8): Executed 1 of 1 (1 FAILED) (0 secs / 0.031 secs)
PhantomJS 1.9.8 (Windows 8): Executed 1 of 1 (1 FAILED) ERROR (0.028 secs / 0.031 secs)
Warning: Task "karma:development" failed. Use --force to continue.
我最后注释掉了导致错误的 angular-mocks 行(第 1646 行),发现由于某种原因,我发送的数据在某处的格式不正确。这是现在的错误输出:
Running "karma:development" (karma) task
INFO [karma]: Karma v0.12.16 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8)]: Connected on socket xGP0gRaa3WEdNVw1DrQm with id 89049214
PhantomJS 1.9.8 (Windows 8): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
PhantomJS 1.9.8 (Windows 8) LoginController successfully logging in should redirect to /blog when authenticated FAILED
Error: Expected POST /api/login with different data
EXPECTED: {"username":"danny@ravenartmedia.com","password":"test"}
GOT: username=danny%40ravenartmedia.com&password=test
at $httpBackend (c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1196)
at sendReq (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9616)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9331
at processQueue (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13171)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13187
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14384
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14200
at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1525
at c:/Projects/dannyschreiber/public/src/core/security/login-controller.spec.js:6
Error: [$rootScope:inprog] $digest already in progress
http://errors.angularjs.org/1.3.9/$rootScope/inprog?p0=%24digest
at beginPhase (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14738)
at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14180
at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1557
at c:/Projects/dannyschreiber/public/src/core/security/login-controller.spec.js:6
PhantomJS 1.9.8 (Windows 8): Executed 1 of 1 (1 FAILED) (0 secs / 0.032 secs)
PhantomJS 1.9.8 (Windows 8): Executed 1 of 1 (1 FAILED) ERROR (0.029 secs / 0.032 secs)
Warning: Task "karma:development" failed. Use --force to continue.
关键信息是:
Error: Expected POST /api/login with different data
EXPECTED: {"username":"danny@ravenartmedia.com","password":"test"}
GOT: username=danny%40ravenartmedia.com&password=test
为什么我的 json 被修改了?
这是来自 RestService 的 postData 函数,我已经在很多项目中使用它,没有出现问题:
var postData = function(url, params, data, successFunction, errorFunction, config) {
if(config && config.hasOwnProperty('showLoader')){
$rootScope.showLoader = config.showLoader;
}
$http({
method: 'POST',
url: url,
params: params,
data: data,
cache: false
})
.success(function(data, status, headers, config) {
$rootScope.showLoader = false;
if (successFunction === undefined) {
_defaultSuccessFunction(data, status, headers, config);
}
else {
successFunction(data, status, headers, config);
}
})
.error(function (data, status, headers, config) {
$rootScope.showLoader = false;
if (status !== 0){
_processError(data, status, headers, config, errorMsg, errorFunction);
}
});
};
编辑: 我能够在 plnkr 中连接所有这些:http://plnkr.co/edit/lJTx0ldR9nEnlYbU5pJd并且测试通过了....但是完全相同的代码给了我我在这篇文章中提到的错误。我正在运行 Angular 和 Angular-Mocks 的 1.3.9 版。
最佳答案
您的辅助方法定义为 function(url, params, data, successFunction, errorFunction, config)
,其中 data
是第三个参数。
将此与您的调用进行比较:
RestService.postData('/api/login', null, null, {username: username, password: password}, _success, 'Invalid login, please try again', _error, {showLoader: true});
在这里,您将数据作为第四个参数传递。所以我认为您想删除其中一个 null
值。不幸的是,Javscript 不会警告错误数量的参数(只是忽略它们)。
编辑:
同时你已经编辑了你的问题,但是你对 postData
的调用可能仍然不正确。
我已经使用您的代码准备了一个 fiddle :http://jsfiddle.net/qwteyak3/1/
postData
的第一次调用获取数据作为 params
参数。这告诉 $http
将其作为表单数据发送。第二次调用将它传递到 data
字段中。 $http
检查数据,找到一个对象,然后将其作为 JSON 正文发送。
运行 fiddle 时,Chrome 的网络选项卡向我显示了对 http://fiddle.jshell.net/echo/json?password=123&username=test
的第一次调用请求和 http://fiddle.jshell.net/echo/json
(正文中有数据)。
希望对您有所帮助。
关于javascript - 由于 Angular 模拟接收到不正确的 json 格式,Jasmine 测试无法进行 $httpbackend 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28012603/