我正在使用AngularJS,Karma,Mocha,Chai,Chai-as-promise,Sinon.
我正在尝试下面的控制器.我无法模拟服务User并测试控制器中的.then()部分.
控制器代码
.controller('SignupPhoneCtrl',function(User,$scope) { $scope.sendPhoneNumber = function(countryCode,phoneNumber){ User.sendPhoneNumber(countryCode,phoneNumber) .then(function(result){ if(result == "success"){ //I WANT TO TEST THIS SECTION return "success"; } //I WANT TO TEST THIS SECTION return "fail"; }); } })
ControllerTest代码
describe('Controller: Signup-phone',function() { var scope; var UserMock; var SignupPhoneCtrl; beforeEach(function() { module('starter.controllers'); }); beforeEach(inject(function($rootScope,$controller,$q){ scope = $rootScope.$new(); UserMock = { sendPhoneNumber: function(countryCode,phoneNumber){ var deferred = $q.defer(); // console.log("called"); //This part is being called deferred.resolve('foo'); return deferred.promise; } }; SignupPhoneCtrl = $controller("SignupPhoneCtrl",{$scope: scope,User: UserMock}); })) it('should return asdf',function(){ scope.$digest(); //WHAT SHOULD I WRITE HERE? }) });
我已尝试过以下但断言部分未被调用.
scope.sendPhoneNumber(12,53452123).then(function(result){ result.should.equal("fail"); //THIS SECTION IS NOT CALLED })
我尝试了下面的内容,但它给出了错误:’undefined’不是一个函数(评估’promise.then.bind(promise)’
scope.sendPhoneNumber(12,53452123).should.eventually.equal("fail");
sendPhoneNumber(12,53452123)返回Object {$$state:Object {status:0}}
我试图添加sinon.spy(UserMock,’sendPhoneNumber’),但它没有任何区别.
解决方法
问题是,$scope.sendPhoneNumber不返回任何内容.尝试
return User.sendPhoneNumber(...
在你的控制器方法.
此外,如果你只是想立即解决你的模拟中的承诺,我发现这很好用,并节省你设置一个延迟对象
UserMock = { sendPhoneNumber: function(countryCode,phoneNumber){ return $q.when('foo'); } };
话虽这么说,你可能希望能够控制每个测试中的解析值,这样更有意义……
var scope; var UserMock; var SignupPhoneCtrl; var deferred; // snip inject(function($rootScope,$q) { deferred = $q.defer(); UserMock = { sendPhoneNumber: function() { return deferred.promise; } }; }); // snip it('tests for success',inject(function($rootScope) { deferred.resolve('success'); scope.sendPhoneNumber(...).then(...); $rootScope.$apply(); })); it('tests for failure',inject(function($rootScope) { deferred.resolve('not success'); scope.sendPhoneNumber(...).then(...); $rootScope.$apply(); }));