I am trying to do an unit test a service in my case
In my test controller
myService.getItem('/api/toy/' + scope.id).success(
function(toy) {
$scope.toy = toys.details;
}
);
MyService
angular.module('toyApp').service('myService', ['$http',
function($http) {
var service = {};
return {
getItem: function(url) {
return $http.get(url);
},
};
}
]);
Test file.
describe('toy ctrl', function () {
var $httpBackend, ctrl, myService;
beforeEach(module('toyApp'));
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, __myService_) {
scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_;
myService = _myService_;
ctrl = _$controller_('toyCtrl', {
$scope: scope
});
}));
describe('call my service', function() {
it('should make request when app loads', function() {
$httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456 });
myService.getItem('/api/toy/123').then(function(toy){
expect(scope.toy.detail).toBe(456);
})
$httpBackend.flush();
})
})
I am getting
Error: Unexpected request: GET /api/toy/123
No more request expected
If I take out $httpBackend.flush()
, the error is gone but it won't cover the
function(toy) {
$scope.toy = toys.details;
}
part. I want to cover the function call and not sure how to do this. Can anyone help me about it? Thanks a lot
Seems like you are "unit" testing the controller, so you don't have to bring in the service in picture as you just need to test the controller logic. You could create a mock service and inject it while creating the controller in your test.
Example:
var mockItem = {details:{//somestuff}, id:'1'};// set up a mock object to test against later
//....
beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_, _$q_) {
scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_;
//Set up mock
myService = jasmine.CreateSpyObj('myService', ['getItem']);
myService.getItem.and.returnValue($q.when(mockItem ));
ctrl = _$controller_('toyCtrl', {
$scope: scope,
myService: myService //<-- Pass it here
});
}));
//.....Assuming you are making the call when controller is instantiated
it('should make request when app loads', function() {
expect(myService.getItem).toHaveBeenCalled();
//You could also check as below
//expect(myService.getItem).toHaveBeenCalledWith(expectedidpassedin);
scope.$digest(); //Resolve $q promise callback
expect($scope.toy).toEqual(mockItem .details);
});
If you are specifically unit testing your service alone you could do:
it('should make request when app loads', function() {
var resp;
$httpBackend.expectGET('/api/toy/123').respond({id:123, detail:456});
myService.getItem('/api/toy/123').then(function(response){
resp = response.data;
});
$httpBackend.flush();
expect(resp.detail).toEqual(456);
});
In your controller instead of chaining success
use then
myService.getItem('/api/toy/' + scope.id).then(
function(response) {
$scope.toy = response.toys.details;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With