javascript

  • controller(‘RecipeDetailController’, function($scope,dataService,$location) { const vm = this; const init = () => { const path = $location.path(); if (path.includes(“edit”)) { let id = path.slice(6); dataService.getID(id,function(response) { vm.recipe = response.data; vm.title = response.data.name; vm.editCategory = response.data.category; }); } else if (path.includes(“add”)) { vm.recipe = { name: “”, description: “”, category: “”, prepTime: 0, cookTime: 0, ingredients: [ { foodItem: “”, condition: “”, amount: “” } ], steps: [ { description: “” } ] } vm.title = ‘Add New Recipe.’
  • Unit Testing Controllers √has a test to test that tests are testing √should have a RecipesController √should have a RecipeDetailController ×should call the getAllRecipes service and return response Expected undefined to be [ Object({ name: ‘recipename’ }) ].
  • toEqual([‘dog’,’cat’,’horse’,’cow’]); }); it(‘should take you to the /add route when the addRecipe method is called’, inject(function($location) { const controller = $controller(‘RecipesController’,{$scope:$scope}); controller.addRecipe(); expect($location.path()).toEqual(‘/add’); })); });
  • I am working on the Single Page Application with AngularJS project for the Treehouse Full Stack JavaScript TechDegree and I am trying to do unit tests on the controllers.
  • RecipeDetailController’,{$scope:$scope}); expect(controller).

I am working on the Single Page Application with AngularJS project for the Treehouse Full Stack JavaScript TechDegree and I am trying to do unit tests on the controllers. To test the controllers that make api calls to the dataService I have to mock the dataService and I can not figure out how to do this correctly. I have read article after article on unit testing angular and I am so lost that I have no idea what to do next.

@SmellyDogCoding: Anybody have any expertise in mocking services that return a promise to test a controller in angularjs?

I am working on the Single Page Application with AngularJS project for the Treehouse Full Stack JavaScript TechDegree and I am trying to do unit tests on the controllers. To test the controllers that make api calls to the dataService I have to mock the dataService and I can not figure out how to do this correctly. I have read article after article on unit testing angular and I am so lost that I have no idea what to do next.

controllers.js:

(function() { ‘use strict’; angular.module(‘app’) .controller(‘RecipesController’, function(dataService,$location) { const vm = this; vm.init = () => { vm.hidden = true; dataService.getAllRecipes(function(response) { vm.recipes = response.data; vm.getCategories(response.data); }); } vm.selectCategory = (category) => { if (category === null) { vm.init(); } else { dataService.getCategory(category,function(response) { vm.recipes = response.data; }); } }; vm.getCategories = (data) => { let categories = new Set(); for (let item of data) { categories.add(item.category); } vm.categories = Array.from(categories); }; vm.addRecipe = () => { $location.path(‘/add’); } vm.deleteRecipe = (recipe,$index) => { vm.toDelete = recipe.name; vm.hidden = false; vm.deleteIt = () => { vm.hidden = true; dataService.deleteRecipe(recipe._id,function(response) { vm.init(); }); } } vm.init(); }) .controller(‘RecipeDetailController’, function($scope,dataService,$location) { const vm = this; const init = () => { const path = $location.path(); if (path.includes(“edit”)) { let id = path.slice(6); dataService.getID(id,function(response) { vm.recipe = response.data; vm.title = response.data.name; vm.editCategory = response.data.category; }); } else if (path.includes(“add”)) { vm.recipe = { name: “”, description: “”, category: “”, prepTime: 0, cookTime: 0, ingredients: [ { foodItem: “”, condition: “”, amount: “” } ], steps: [ { description: “” } ] } vm.title = ‘Add New Recipe.’ } dataService.getAllCategories(function (response) { vm.categories = response.data; let index = response.data.findIndex(item => item.name === $scope.editCategory); if (index === -1) { vm.initial = {“name”: “Choose a Category”}; } else { vm.initial = $scope.categories[index]; } }); dataService.getAllFoodItems(function (response) { vm.foods = response.data; }); } vm.addItem = (item) => { if (item === ‘ingredient’) { vm.recipe.ingredients.push({amount: “amount”, condition: “condition”, foodItem: “”}); } else if (item === ‘step’) { vm.recipe.steps.push({description: “description”}); } }; vm.deleteItem = (item,$index) => { if (item === ‘ingredient’) { vm.recipe.ingredients.splice($index,1); } else if (item === ‘step’) { vm.recipe.steps.splice($index,1); } } vm.saveChanges = (recipe) => { vm.errors = []; const buildErrorArray = (errorArray) => { for (let item of errorArray) { vm.errors.push(item.userMessage); } } const collectErrors = (response) => { if (response.data.errors.category) { buildErrorArray(response.data.errors.category) } if (response.data.errors.ingredients) { buildErrorArray(response.data.errors.ingredients) } if (response.data.errors.name) { buildErrorArray(response.data.errors.name) } if (response.data.errors.steps) { buildErrorArray(response.data.errors.steps) } } if (recipe._id) { dataService.updateID(recipe,function(response) { $location.path(‘/’); }, function(response) { collectErrors(response) }); } else { dataService.addRecipe(recipe,function(response) { $location.path(‘/’); }, function(response) { collectErrors(response) }); } } vm.cancelChanges = () => { $location.path(‘/’); } init(); }); }());

services.js:

(function() { ‘use strict’; angular.module(‘app’) .service(‘dataService’, function($http,errors,httpErrors) { this.getAllRecipes = function (callback) { $http.get(‘http://localhost:5000/api/recipes’) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; this.getAllCategories = function (callback) { $http.get(‘http://localhost:5000/api/categories’) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; this.getAllFoodItems = function (callback) { $http.get(‘http://localhost:5000/api/fooditems’) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; this.getCategory = function(category,callback) { $http.get(‘http://localhost:5000/api/recipes?category=’ + category) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; this.getID = function (id,callback) { $http.get(‘http://localhost:5000/api/recipes/’ + id) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; this.updateID = function (data,success,error) { $http.put(‘http://localhost:5000/api/recipes/’ + data._id, data) .then(success,error).catch(errors.catch()); }; this.addRecipe = function (data,success,error) { $http.post(‘http://localhost:5000/api/recipes’, data) .then(success,error).catch(errors.catch()); }; this.deleteRecipe = function (id,callback) { $http.delete(‘http://localhost:5000/api/recipes/’ + id) .then(callback,httpErrors.display(‘HTTP Error’)) .catch(errors.catch()); }; }); }());

controllersSpec.js:

describe(“Unit Testing Controllers”, function() { beforeEach(angular.mock.module(‘app’)); let $scope; let getAllRecipesMock; beforeEach(inject(function(_$controller_,_$rootScope_,$q) { $controller = _$controller_; $scope = _$rootScope_.$new(); getAllRecipesMock = { getAllRecipes: function() { var deferred = $q.defer(); deferred.resolve([{name: “recipename”}]); return deferred.promise; } } })); it(‘has a test to test that tests are testing’, function() { expect(2 + 2).toEqual(4); }); it(‘should have a RecipesController’, function() { const controller = $controller(‘RecipesController’,{$scope:$scope}); expect(controller).toBeDefined(); }); it(‘should have a RecipeDetailController’, function() { const controller = $controller(‘RecipeDetailController’,{$scope:$scope}); expect(controller).toBeDefined(); }); it(‘should call the getAllRecipes service and return response’, inject(function() { const controller = $controller(‘RecipesController’,{$scope:$scope,dataService:getAllRecipesMock}); $scope.$digest(); expect(controller.recipes).toBe([{name: “recipename”}]); })); it(‘should remove duplicate categories’, function() { const controller = $controller(‘RecipesController’,{$scope:$scope}); let data = [{‘category’:’dog’},{‘category’:’cat’},{‘category’:’horse’},{‘category’:’dog’},{‘category’:’cow’}]; controller.getCategories(data); expect(controller.categories).toEqual([‘dog’,’cat’,’horse’,’cow’]); }); it(‘should take you to the /add route when the addRecipe method is called’, inject(function($location) { const controller = $controller(‘RecipesController’,{$scope:$scope}); controller.addRecipe(); expect($location.path()).toEqual(‘/add’); })); });

This is the result I get when I run the tests:

Unit Testing Controllers √has a test to test that tests are testing √should have a RecipesController √should have a RecipeDetailController ×should call the getAllRecipes service and return response Expected undefined to be [ Object({ name: ‘recipename’ }) ]. at Object. (test/controllersSpec.js:38:32) at Object.invoke (node_modules/angular/angular.js:4839:19) at Object.WorkFn (node_modules/angular-mocks/angular-mocks.js:3155:20) √should remove duplicate categories √should take you to the /add route when the addRecipe method is called Chrome 55.0.2883 (Windows 10 0.0.0): Executed 6 of 6 (1 FAILED) (0.235 secs / 0.084 secs) TOTAL: 1 FAILED, 5 SUCCESS 1) should call the getAllRecipes service and return response Unit Testing Controllers Expected undefined to be [ Object({ name: ‘recipename’ }) ]. at Object. (test/controllersSpec.js:38:32) at Object.invoke (node_modules/angular/angular.js:4839:19) at Object.WorkFn (node_modules/angular-mocks/angular-mocks.js:3155:20)

javascript

You might also like More from author

Comments are closed, but trackbacks and pingbacks are open.