I have a service which contains a resource factory like this:
serviceModule.factory('ProjectResource', ['$resource', function($resource){
return $resource('/projects/:id.json', {}, {
'query': {method: 'GET', isArray: true}}
);
}]);
In a form, which resides in a controller, I inject the serviceModule, and I create a new instance of the resource object:
$scope.project = new ProjectResource({name: 'Enter a name'})
I have some issues with mocking it. I have tried creating a mock object like this, and injecting it in the controller:
mockProjectResource = {
query: function(){
deferred = $q.defer();
deferred.resolve({id: 1, :name:'test'});
return deferred.promise;
}
};
No matter the unit test, I get the error:
TypeError: undefined is not a function
Which points to the initialization of the Project Resource object ($scope.project = new ProjectResource({name: 'Enter a name'})
).
Are there any good way to mock the new ProjectResource(...)
?
Another way to mock a resource based service is like this:
// the name of an object should start with a capital letter
// in the case where we create a function object (as opposed to
// a literal object).
MockProjectResource = function(){};
// we add the "query" method to the "prototype" property
MockProjectResource.prototype.query = function(){
deferred = $q.defer();
deferred.resolve({id: 1, :name:'test'});
return deferred.promise;
};
Mocking the query function like above works in the case where the controller expects the promise to be returned as a result of the call, e.g.:
var projectController = angular.module('projectController', []);
projectController.controller('ProjectController', ['$scope', 'ProjectResource',
function($scope, ProjectResource) {
var promise = ProjectResource.query();
promise.then(function(data) {
console.log(data);
},
function(err){
console.log(err);
});
}]);
However, if the controller expects the result to be sent in a callback, like this:
ProjectResource.query(function(data) {
console.log(data);
},
function(err){
console.log(err);
});
then, the service needs to be mocked like this:
MockProjectResource.prototype.query = function(success, error){
var deferred = q.defer();
var promise = deferred.promise;
promise.then(success, error);
deferred.resolve({id: 1, :name:'test'});
};
For a full example, see my answer to a similar question:
How do you mock an angularjs $resource factory
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