但是我仍然难以有效地测试触发成功和错误方法操作.我还需要增加检查消息广播的期望.
为了测试上面提到的场景,我设计了一个我已经包含在Plunker中的hack,但我相信应该有更好的方法来测试这些场景.
任何有关如何克服此问题并测试响应消息状态的线索将非常感激.
问题
我为我的测试设置了$httpBackend的预期值/响应,但是当我运行$httpBackend.flush()时,它无法指示下面提到的错误.
指示错误消息
Error: Unexpected request: GET https://192.168.1.10:3334/res?t1=CHECK&t2='?'&req={"_msgType":"Login_msg","UserName":"e@e.com","Password":"123"}
我确实找到了一些讨论这个问题域的有用链接,它们确实帮助我缩小了问题范围.但我似乎还无法弄清楚这个单元测试失败的具体原因.
有用的堆栈溢出问题
> Angular mock $httpBackend give No pending request to flush
> Unit testing AngularJS with $httpBackend gives “Error: Unexpected Request”
> Testing Angular $resource with external service
> Why do I receive error … unexpected request
> Mocking $httpBackend
有用的外部资源
> AngularJS Tests With An HTTP Mock
> Unit Testing $http service in Angular.js
> Angularjs Tutorial: Testing using ngMock $httpBackend and karma.
> Angular JS – Unit Testing – Services
> AngularJS Tests With An HTTP Mock
我也尝试了moving the flush() call around,并且在测试中发出$http请求时也尝试了calling $apply or $digest,如此处所示.
要测试的AngularJS服务
app.service('restService',['$log','$http','$rootScope',function($log,$http,$rootScope) { this.location = null; this.port = null; this.sendRequest = function(host,port,param1,param2,requestMsg) { this.location = host; this.port = port; $http.get('https://'+host+":"+port+"/res?t1="+param1+"&t2="+param2+"&req="+JSON.stringify(requestMsg)). success(function(data) { //Need to add expectations to check success operations $log.log('response received',data); var msgData = data; $rootScope.successCalled = true; $rootScope.response = data; if(msgData.hasOwnProperty('_msgType')) { $log.log('broadcast for channel',msgData._msgType); $rootScope.$broadcast(msgData._msgType,msgData); } }). error(function(){ //Need to add expectations to check error method operations var httpErrMsg = {_msgType:'HTTPErr',host:host,port:port,t1:param1,t2:param2,requestMsg:requestMsg}; $rootScope.errorCalled = true; $rootScope.response = data; $rootScope.$broadcast(httpErrMsg._msgType,httpErrMsg); }); } this.getIP = function() { return this.location; } this.getPort = function() { return this.port; } }])
用于测试服务的规范
"use strict"; describe("Rest service test",function() { var $scope,$location,httpBackend,$log,restService,loginMsg ; beforeEach(module('app')); beforeEach(inject(function (_restService_) { restService = _restService_; })); beforeEach(inject(function($rootScope,_$location_,$httpBackend,_$log_) { $scope = $rootScope.$new(); $location = _$location_; httpBackend = $httpBackend; $log = _$log_; loginMsg={ _msgType:"Login_msg",UserName:"e@e.com",Password:"123"}; })); afterEach(function() { httpBackend.verifyNoOutstandingExpectation(); httpBackend.verifyNoOutstandingRequest(); }); describe("Service : Rest Service",function() { it('Should start with location and port undefined',function() { expect(restService.location).toEqual(null); expect(restService.port).toEqual(null); }); it("check if method exists",function() { expect(restService.sendRequest).toBeDefined(); }); it("GetIP method Exists ",function() { expect(restService.getIP).toBeDefined(); }); it("GetPort method Exists ",function() { expect(restService.getPort).toBeDefined(); }); it("GetIP Value ",function() { restService.location = '192.168.1.10'; expect(restService.location).toEqual('192.168.1.10'); }); it("GetPort Value ",function() { restService.port = '3334'; expect(restService.port).toEqual('3334'); }); it("Execute sendRequest()",function() { httpBackend.when('GET','https://192.168.1.10:3334/res?t1=CHECK&t2=\'?\'&req={"_msgType":"Login_msg","Password":"123"}') .respond ({SessionId:"2103337586",Status:"user e@e.com not found ",EMail:"e@e.com",rejectCode:1,rejectReason:"Invalid username or password",_msgType:"LoginReply_msg"}); restService.sendRequest("192.168.1.10","3334","CHECK","'?'",loginMsg); httpBackend.flush(); expect(restService.location).toEqual('192.168.1.10'); expect(restService.port).toEqual('3334'); expect($scope.successCalled).toBe(true); expect($scope.response).not.toBe(null); expect($scope.response._msgType).toEqual('LoginReply_msg'); }); }); });
解决方法
beforeEach(inject(function($rootScope,_$log_) { $scope = $rootScope.$new(); $location = _$location_; httpBackend = $httpBackend; $log = _$log_; loginMsg={ _msgType:"Login_msg",Password:"123"}; httpBackend.expectGET(/192.168.1.10:3334/i).respond(function (){ return [/*mockResponse*/]; }); }));