I have been playing a bit with the following code and I am not able to find the issue, the test fails wit the following message: "Expected undefined not to be undefined."
I have a Service which returns a promise to my controller. In the controller, I am using $q.all to do some stuff immediately after I get the promise resolved.
I tried to follow this example, but the big difference I see is that in the example it has the call in the root of the controller and I have the service call inside of the method "$scope.CustomerTest" so I have this additional line to before the apply ( $scope.$apply() ) "$scope.CustomerTest('Mr');":
http://www.bradoncode.com/blog/2015/07/13/unit-test-promises-angualrjs-q/
This is my test code:
var $scope;
var $q;
var deferred;
var $httpBackend;
//Inject the module "before each test"
beforeEach(angular.mock.module('marketingApp'));
beforeEach(inject(function ($controller,_$httpBackend_, _$rootScope_, _$q_, marketingService) {
$q = _$q_;
$scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_;
// We use the $q service to create a mock instance of defer
deferred = _$q_.defer();
// Use a Jasmine Spy to return the deferred promise
spyOn(marketingService, 'getTitleSuggested').and.returnValue(deferred.promise);
// Init the controller, passing our spy service instance
$controller('customerController', {
$scope: $scope,
marketingService: marketingService
});
}));
it('should resolve promise', function () {
// Setup the data we wish to return for the .then function in the controller
var titles = [{ "Id": 1, "Name": "Mr" }];
deferred.resolve(titles);
$httpBackend.when('GET', '/MarketingCustomers/GetTitleSuggested')
.respond(200, titles);
//I call to the controller method here.
$scope.CustomerTest('Mr');
$scope.$apply();
// Since we called apply, not we can perform our assertions
//expect($scope.TitlesTest).not.toBe(undefined);
expect($scope.SelectedCustomerTitle).toEqual('Mr');
//expect($scope.error).toBe(undefined);
});
And this is the plunker:
http://plnkr.co/edit/3IMzqH1yKW8kazZFWaA0?p=preview
Commenting the first test (it) of the controller.spec.js the other two test works. Any help please?
Resolved my issue here is again the plunker if someone has similar problem, hopefully it can helps.
Here is the test:
describe('CustomerController.js', function() {
var results = [{
"Id": 1,
"Name": "Mr"
}];
var $controller;
var $q;
var $rootScope;
var $scope;
var marketingService;
beforeEach(angular.mock.module('marketingApp'));
beforeEach(inject(function(_$rootScope_, $controller, _$q_,
_marketingService_) {
$scope = _$rootScope_.$new();
$q = _$q_;
$rootScope = _$rootScope_;
marketingService = _marketingService_;
$controller('customerController', {
$scope: $scope,
$rootScope: $rootScope
});
spyOn(marketingService, 'getTitleSuggested').and.callFake(function() {
var deferred = $q.defer();
deferred.resolve(results);
return deferred.promise;
});
}));
it('It should call the service" ', function() {
$scope.CustomerTest('Mr');
expect(marketingService.getTitleSuggested).toHaveBeenCalledWith('Mr');
});
it('It should populate the "$scope.TitlesTest" ', function() {
$scope.CustomerTest('Mr');
$rootScope.$apply();
expect($scope.hello).toEqual('Hello Mr Marcos');
expect($scope.Titles[0].Name).toBe('Mr');
expect($scope.Titles).toBe(results);
});
});
and this is the plunker: http://plnkr.co/edit/3IMzqH1yKW8kazZFWaA0?p=preview