{"id":14498,"date":"2016-08-26T12:15:06","date_gmt":"2016-08-26T09:15:06","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=14498"},"modified":"2016-08-24T13:57:43","modified_gmt":"2016-08-24T10:57:43","slug":"angularjs-unit-testing-karma-jasmine","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/","title":{"rendered":"AngularJS Unit Testing With Karma and Jasmine"},"content":{"rendered":"<p>One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects grow in complexity and the number of developers. It also provides new devs with documentation on how to use existing code.<\/p>\n<p>In my last article, I explained <a href=\"https:\/\/keyholesoftware.com\/2016\/05\/16\/test-driven-intro-angular2\/\" target=\"_blank\">how to use Test-Driven Development (TDD) to create a simple Angular 2 application<\/a>. This time around, I will be taking a different approach for unit testing an Angular application. In this post I will write unit tests for an existing reference Angular application and explain how to make good use of testing tools for Angular.<\/p>\n<h3>Tests or Code First?<\/h3>\n<p>Some places require their developers to use TDD while some do not. The approach you use is up to either your individual or organizational philosophy. TDD does offer quite a few benefits if you can get in to the habit. Regardless of the approach used, you will be far better off with unit tests in place than if you have none.<\/p>\n<p>As projects grow in complexity and mature, having good automated testing in place can save a lot of headaches. When a new developer joins an existing project, unit tests can be a valuable source of documentation to teach how the code is supposed to function. If they are assigned to fix a bug in code that they did not write, and make a change that fixes their small issue but breaks other requirements, the unit tests will let them know that there is an issue with their code change.<\/p>\n<p>Catching problems like these at the development stage will save time. If there are no unit tests to let the developer know there is an issue early on, their changes could potentially make it to testers or even production before the new issue is caught. Unit tests may not catch every bug that will be introduced, but it should give a level of confidence that business logic will continue to function in the same way.<\/p>\n<h3>Who has time to write tests?<\/h3>\n<p>As developers we\u2019ve all been here. I know I have. When we work on projects we always have tight deadlines and things need to get done. Unit testing is thought of as optional since it doesn\u2019t have a direct effect on how the product functions. But if you commit to writing tests early on in a project it will save time in the long run.<\/p>\n<p>Writing tests can seem tedious at times, but good tests can be a safety net that can prevent you from introducing regression bugs. The time you save can be better spent on adding new features or refactoring your code.<\/p>\n<h2>What We Are Testing<\/h2>\n<p>For this article, I have put together a simple AngularJS application that can be downloaded from Github <a href=\"https:\/\/github.com\/mbrown333\/unit-testing-demo-book-inventory-app\">here<\/a>. As I discuss topics, I will be using this application to give examples to demonstrate.<\/p>\n<p>The example application is a book inventory application that performs basic CRUD operations.<\/p>\n<h2>Karma<\/h2>\n<p>We will be using Karma as a test runner for our test cases. To set up Karma, first you will need to install the Karma command line interface using <code>npm install karma-cli -g<\/code>.<\/p>\n<p>In order for Karma to run our tests we will need a <code>karma.conf.js<\/code> configuration file to our project. We can create this file ourselves or have <code>karma-cli<\/code> generate one for us by using <code>karma init<\/code> on the command line. Below is my example config file:<\/p>\n<p><b>karma.conf.js<\/b><\/p>\n<pre class=\"brush:java\">module.exports = function(config) {\r\n  config.set({\r\n\r\n    \/\/ base path that will be used to resolve all patterns (eg. files, exclude)\r\n    basePath: '',\r\n\r\n    \/\/ frameworks to use\r\n    \/\/ available frameworks: https:\/\/npmjs.org\/browse\/keyword\/karma-adapter\r\n    frameworks: ['jasmine'],\r\n\r\n    \/\/ list of files \/ patterns to load in the browser\r\n    files: [\r\n      'client\/lib\/angular\/angular.js',\r\n      'client\/lib\/angular-mocks\/angular-mocks.js',\r\n      'client\/lib\/angular-ui-router\/angular-ui-router.js',\r\n      'client\/lib\/angular-ui-router\/release\/angular-ui-router.js',\r\n      'client\/lib\/lodash\/lodash.js',\r\n      'client\/lib\/moment\/moment.js',\r\n      'client\/app\/app.js',\r\n      'client\/app\/modules.js',\r\n      'client\/app\/main.js',\r\n      'client\/app\/**\/*.js',\r\n      'client\/test\/**\/*.spec.js',\r\n      'client\/test\/**\/*.spec.js'\r\n    ],\r\n\r\n    \/\/ list of files to exclude\r\n    exclude: [\r\n    ],\r\n\r\n    \/\/ preprocess matching files before serving them to the browser\r\n    \/\/ available preprocessors: https:\/\/npmjs.org\/browse\/keyword\/karma-preprocessor\r\n    preprocessors: {\r\n    },\r\n\r\n    \/\/ test results reporter to use\r\n    \/\/ possible values: 'dots', 'progress'\r\n    \/\/ available reporters: https:\/\/npmjs.org\/browse\/keyword\/karma-reporter\r\n    reporters: ['progress'],\r\n\r\n    \/\/ web server port\r\n    port: 9876,\r\n\r\n    \/\/ enable \/ disable colors in the output (reporters and logs)\r\n    colors: true,\r\n\r\n    \/\/ level of logging\r\n    \/\/ possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\r\n    logLevel: config.LOG_INFO,\r\n\r\n    \/\/ enable \/ disable watching file and executing tests whenever any file changes\r\n    autoWatch: true,\r\n\r\n    \/\/ start these browsers\r\n    \/\/ available browser launchers: https:\/\/npmjs.org\/browse\/keyword\/karma-launcher\r\n    browsers: ['PhantomJS'],\r\n\r\n    \/\/ Continuous Integration mode\r\n    \/\/ if true, Karma captures browsers, runs the tests and exits\r\n    singleRun: false,\r\n\r\n    \/\/ Concurrency level\r\n    \/\/ how many browser should be started simultaneous\r\n    concurrency: Infinity\r\n  })\r\n}<\/pre>\n<p>The important part here is the files property. We need to tell Karma where to find all of our JavaScript libraries, source files, and finally our test specs.<\/p>\n<p>After we have this file in place, we can run our tests by running <code>karma start<\/code> on the command line. With <code>autoWatch<\/code> set to true, Karma will watch all of our files for changes and automatically re-run all of our tests every time a file is modified.<\/p>\n<h2>File Structure\/Naming Convention<\/h2>\n<p>If you download the example code, you\u2019ll see in the client folder I have the source code for our Angular application in the app\/ folder. The test specs can be found in the test\/ folder. The test directory structure is set up to mirror the structure of the app\/ folder so that it is immediately obvious what test specs are trying to test.<\/p>\n<p>The naming convention for the tests is to add spec to the file name of the target file that is being tested. In this example I use the format <code>fileName.spec.js<\/code>, but it is common to use <code>fileNameSpec.js<\/code> as well.<\/p>\n<h2>Setting Up Our tests<\/h2>\n<p>You\u2019ll see in the examples below that all of our test specs are set up similarly. Each spec is contained in a describe function like this:<\/p>\n<pre class=\"brush:java\">describe('Component we are testing', function() {\r\n\r\n});<\/pre>\n<p>We give a descriptive name to describe what we are testing. If we have failing tests this will print in your test output so make sure it tells you enough that you know where to look for issues.<\/p>\n<p>You can nest these describe functions as well. So if you want to have a separate block for each function in a controller you could do the following:<\/p>\n<pre class=\"brush:java\">describe('Controller - Example Controller', function() {\r\n\r\n  describe('add()', function() {\r\n    \/\/ test add function here\r\n  });\r\n\r\n  describe('view()', function() {\r\n    \/\/ test view function here\r\n  });\r\n\r\n  describe('submit()', function() {\r\n    \/\/ test submit function here\r\n  });\r\n\r\n});<\/pre>\n<p>The other part of our setup that you will see that our specs have in common are the <code>beforeEach<\/code> and <code>afterEach<\/code> functions.<\/p>\n<pre class=\"brush:java\">describe('Controller', function() {\r\n\r\n  beforeEach(function() {\r\n    \/\/ Perform set up here - runs before each individual test\r\n  });\r\n\r\n  afterEach(function() {\r\n    \/\/ Runs after each individual test\r\n  });\r\n\r\n});<\/pre>\n<p>These functions are run either before or after each individual test and allow us to run set up and tear down tasks to give us control over what we are testing.<\/p>\n<p>Like the describe blocks above, these can also be nested if you need to do things differently for different groups of test.<\/p>\n<pre class=\"brush:java\">describe('Controller - Example Controller', function() {\r\n\r\n  beforeEach(function() {\r\n    \/\/ Perform set up here - runs before each individual test\r\n  });\r\n\r\n  afterEach(function() {\r\n    \/\/ Runs after each individual test\r\n  });\r\n\r\n  describe('add()', function() {\r\n    beforeEach(function() {\r\n      \/\/ Additional setup for add()\r\n    });\r\n\r\n    afterEach(function() {\r\n      \/\/ Additional tear down for add()\r\n    });\r\n  });\r\n\r\n  describe('view()', function() {\r\n    beforeEach(function() {\r\n      \/\/ Additional setup for view()\r\n    });\r\n\r\n    afterEach(function() {\r\n      \/\/ Additional tear down for view()\r\n    });\r\n  });\r\n\r\n  describe('submit()', function() {\r\n    beforeEach(function() {\r\n     \/\/ Additional setup for submit()\r\n    });\r\n\r\n    afterEach(function() {\r\n      \/\/ Additional tear down for submit()\r\n    });\r\n  });\r\n\r\n});<\/pre>\n<p>Most of our tests also use an inject block which is used for injecting Angular components. Example:<\/p>\n<pre class=\"brush:java\">describe('Controller', function() {\r\n\r\n  var controller;\r\n  var $state;\r\n  var $q;\r\n\r\n  beforeEach(function() {\r\n    inject(function($controller, _$state_, _$q_) {\r\n      $state = _$state_;\r\n      $q = _$q_;\r\n\r\n      controller = $controller('ExampleController', {});\r\n    });\r\n  });\r\n});<\/pre>\n<p>If you add underscores before and after the Angular components, you can then store them in variables in case you need to access them outside the inject function. Also we will need <code>$controller<\/code> to create our controllers and inject dependencies for testing.<\/p>\n<p>You will see these blocks throughout our example specs below.<\/p>\n<h2>Testing Controllers<\/h2>\n<p>First we will write unit tests for one of our application\u2019s controllers. Controllers contain our view logic and our application has three controllers. The first is for the main page of the app that lists the current book inventory.<\/p>\n<p><b>booksController.spec.js<\/b><\/p>\n<pre class=\"brush:java\">'use strict';\r\n\r\ndescribe('Controller - Books Controller', function() {\r\n\r\n  var booksController;\r\n  var booksServiceMock;\r\n  var $rootScope;\r\n  var $state;\r\n  var $q;\r\n  var deferredListResponse;\r\n  var mockBookList;\r\n\r\n  beforeEach(function() {\r\n\r\n    module('ui.router.state');\r\n    module('book-inventory-app.books');\r\n\r\n    booksServiceMock = jasmine.createSpyObj('BooksService', ['getBooks', 'deleteBook']);\r\n    mockBookList = [{ id: '1'}, { id: '2' }, { id: '3'}];\r\n\r\n    inject(function($controller, _$rootScope_, _$state_, _$q_) {\r\n      $rootScope = _$rootScope_;\r\n      $state = _$state_;\r\n      $q = _$q_;\r\n\r\n      deferredListResponse = $q.defer();\r\n      booksServiceMock.getBooks.and.returnValue(deferredListResponse.promise);\r\n      deferredListResponse.resolve(mockBookList);\r\n\r\n      booksController = $controller('BooksController', {\r\n        $state: $state,\r\n        BooksService: booksServiceMock\r\n      });\r\n\r\n      spyOn($state, 'go');\r\n\r\n      $rootScope.$apply();\r\n    });\r\n  });\r\n\r\n});<\/pre>\n<p>To start with, here is the setup for our booksController test spec. You can see we declare some variables that will be used at the top. Then in the <code>beforeEach<\/code> block we use <code>module()<\/code> to include any of our Angular modules that we will need to set up our controller.<\/p>\n<p>This controller has a dependency on one of our application\u2019s services so we need to create a mock service. You\u2019ll see we create <code>booksServiceMock<\/code> using <code>jasmine.createSpyObj<\/code> which is a built-in Jasmine utility function for creating mock objects. We just need to specify the name of the mock object and an array of all the function names that our controller will call. If you look a few lines down from where we create <code>booksServiceMock<\/code> you\u2019ll see we can also specify return values. Using <code>booksServiceMock.getBooks.and.returnValue<\/code> we specify that when this function is called in the controller it will return a promise.<\/p>\n<p>You can also create spy functions from existing objects using <code>spyOn<\/code>. In this example we are spying on the go function in angular\u2019s <code>$state<\/code> component.<\/p>\n<p>Now that we have the setup ready, let\u2019s take a look at the tests for this controller:<\/p>\n<pre class=\"brush:java\">it('should load a list of books on inititialization', function() {\r\n  expect(booksController.booksList).toBeDefined();\r\n  expect(booksController.booksList).toBe(mockBookList);\r\n  expect(booksController.booksList.length).toEqual(3);\r\n})<\/pre>\n<p>Here we are testing that our books service provided the mock data list we provided in the setup.<\/p>\n<pre class=\"brush:java\">it('should take the user to the edit screen', function() {\r\n  expect($state.go).not.toHaveBeenCalled();\r\n  booksController.editBook('1');\r\n  expect($state.go).toHaveBeenCalledWith('editBook', {id:'1'})\r\n})\r\n\r\nit('should take the user to the add screen', function() {\r\n  expect($state.go).not.toHaveBeenCalled();\r\n  booksController.addBook();\r\n  expect($state.go).toHaveBeenCalledWith('addBook')\r\n})<\/pre>\n<p>We use our <code>$state.go<\/code> spy function that we created earlier to test that it is being called by the <code>editBook<\/code> and <code>addBook<\/code> functions with the data we expect.<\/p>\n<pre class=\"brush:java\">it('should select a book for the details view', function() {\r\n  expect(booksController.selectedBook).toBeUndefined();\r\n\r\n  booksController.selectBook(mockBookList[0]);\r\n  expect(booksController.selectedBook).toBe(mockBookList[0]);\r\n\r\n  booksController.selectBook(mockBookList[2]);\r\n  expect(booksController.selectedBook).toBe(mockBookList[2]);\r\n})\r\n\r\nit('should call the service to delete a book', function() {\r\n  var deferred = $q.defer();\r\n  booksServiceMock.deleteBook.and.returnValue(deferred.promise);\r\n\r\n  booksController.deleteBook('2');\r\n  expect(booksServiceMock.deleteBook).toHaveBeenCalledWith('2');\r\n})\r\n\r\nit('should reload the book list after successfully deleting a book', function() {\r\n  var deferred = $q.defer();\r\n  booksServiceMock.deleteBook.and.returnValue(deferred.promise);\r\n\r\n  booksServiceMock.getBooks.calls.reset();\r\n  expect(booksServiceMock.getBooks).not.toHaveBeenCalled();\r\n\r\n  booksController.deleteBook('1');\r\n  deferred.resolve(true);\r\n  $rootScope.$apply();\r\n  expect(booksServiceMock.getBooks).toHaveBeenCalled();\r\n})<\/pre>\n<p>You can see in this test that we can reset the calls made on our spy functions by calling <code>calls.reset()<\/code>. That way we can isolate out when a spy function was called only when expected so that we are not getting false positives in our tests.<\/p>\n<h2>Testing Services<\/h2>\n<p>Now that we\u2019ve wrote tests for our controller, we should add testing for our books service. The books service is responsible for communicating with our backend server. It performs basic CRUD operations.<\/p>\n<p>To test components that make HTTP calls we can use <code>$httpBackend<\/code>. This mocks a HTTP server so that we don\u2019t need to have our backend server running while we run our unit tests.<\/p>\n<p>To use <code>$httpBackend<\/code> first, we tell it what calls we are expecting. Then we call <code>.flush()<\/code> and <code>verifyNoOutstandingRequest()<\/code> to first pass all the outstanding HTTP calls through our mock backend and then verify that there are no calls made that we weren\u2019t expecting.<\/p>\n<p>Here\u2019s the setup for our service\u2019s test spec:<\/p>\n<p><b>booksService.spec.js<\/b><\/p>\n<pre class=\"brush:java\">'use strict';\r\n\r\ndescribe('Services - Books Services', function() {\r\n\r\n  var booksService;\r\n  var $httpBackend;\r\n\r\n  beforeEach(function() {\r\n    module('book-inventory-app.books');\r\n\r\n    inject(function(BooksService, _$httpBackend_) {\r\n      $httpBackend = _$httpBackend_;\r\n      booksService = BooksService;\r\n\r\n      $httpBackend.verifyNoOutstandingRequest();\r\n    });\r\n  });\r\n\r\n  afterEach(function() {\r\n    $httpBackend.flush();\r\n    $httpBackend.verifyNoOutstandingRequest();\r\n  });\r\n\r\n});<\/pre>\n<p>The setup is similar to our controller test except that we aren\u2019t creating the service within the inject block. Angular creates our service for us and we simply store a reference to it for use in the tests.<\/p>\n<p>And you\u2019ll see we are calling <code>flush()<\/code> and <code>verifyNoOutstandingRequest()<\/code> in the <code>afterEach<\/code> block as discussed above. This will process all HTTP calls made during the test and then makes sure no calls were made that weren\u2019t expected.<\/p>\n<p>Now for the test cases:<\/p>\n<pre class=\"brush:java\">it('should make a GET call to retrieve a list of books', function() {\r\n  $httpBackend.expectGET('\/api\/books').respond(200, []);\r\n  booksService.getBooks();\r\n});\r\n\r\nit('should make a GET call to retrieve a book', function() {\r\n  $httpBackend.expectGET('\/api\/book\/9').respond(200, {});\r\n  booksService.getBook('9');\r\n});\r\n\r\nit('should make a POST call to create a new book', function() {\r\n  var mockBook = { id: '111' };\r\n  $httpBackend.expectPOST('\/api\/book\/', mockBook).respond(200, true);\r\n  booksService.createBook(mockBook);\r\n});\r\n\r\nit ('should make a PUT call to update an existing book', function() {\r\n  var mockBook = { id: '999' };\r\n  $httpBackend.expectPUT('\/api\/book\/999', mockBook).respond(200, true);\r\n  booksService.saveBook(mockBook, mockBook.id);\r\n});\r\n\r\nit('should make a DELETE call to remove a book', function() {\r\n  $httpBackend.expectDELETE('\/api\/book\/123').respond(200, true);\r\n  booksService.deleteBook('123');\r\n});<\/pre>\n<p>They all follow a similar pattern. We tell the mock backend what call(s) we expect then call the service function that will make that particular backend call.<\/p>\n<p>We can tell the backend the HTTP verb, url, and the request body if it is a POST or PUT. Then we can specify a response code and data.<\/p>\n<h2>Testing Filters<\/h2>\n<p>The final component we will look at unit testing is filters. Filters are usually fairly simple and you\u2019ll see in the example below that testing them is less complicated than controllers or services.<\/p>\n<p><b>formatName.spec.js<\/b><\/p>\n<pre class=\"brush:java\">'use strict';\r\n\r\ndescribe('Filter - Format Name Filter', function() {\r\n\r\n  var formatNameFilter;\r\n\r\n  beforeEach(function() {\r\n    module('book-inventory-app.filters');\r\n\r\n    inject(function($filter) {\r\n      formatNameFilter = $filter('formatName');\r\n    })\r\n  });\r\n});<\/pre>\n<p>To set up our filter tests the only thing we need to do is create an instance of our filter using Angular\u2019s <code>$filter<\/code> and store a reference to it.<\/p>\n<p>With that set up we are now ready to test out the filter. There are two behaviors we want to test.<br \/>\n<a href=\"http:\/\/www.codeproject.com\/script\/Articles\/BlogFeedList.aspx?amid=9076941\" rel=\"tag\">CodeProject<\/a><\/p>\n<pre class=\"brush:java\">it('should return an empty string for empty input', function() {\r\n  expect(formatNameFilter('')).toEqual('');\r\n});\r\n\r\nit('should return the input with the first letter in each work capitalized and the rest un lower case', function() {\r\n  expect(formatNameFilter('JOHN DOE')).toEqual('John Doe');\r\n  expect(formatNameFilter('jOHN dOE')).toEqual('John Doe');\r\n  expect(formatNameFilter('john doe')).toEqual('John Doe');\r\n  expect(formatNameFilter('John Doe')).toEqual('John Doe');\r\n});<\/pre>\n<p>Here we give the filter multiple strings with different casings that we expect to have the same result.<\/p>\n<h2>Wrap Up<\/h2>\n<p>In this article I\u2019ve discussed why we need unit tests and shown examples of how to implement testing in Angular projects. If you are looking to add integrated unit testing to your Angular project I hope this will help guide you in the right direction.<\/p>\n<p>For more examples you can check out the example application <a href=\"https:\/\/github.com\/mbrown333\/unit-testing-demo-book-inventory-app\">here<\/a>.<\/p>\n<p>Thanks for reading, and feel free to leave any questions or comments you might have below!<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/keyholesoftware.com\/2016\/08\/22\/angularjs-unit-testing-with-karma-jasmine\/\">AngularJS Unit Testing With Karma &amp; Jasmine<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a>\u00a0Matthew Brown at the <a href=\"http:\/\/keyholesoftware.com\/\">Keyhole Software<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects grow in complexity and the number of developers. It also provides new devs with documentation on how to use existing code. In my last article, I explained how to &hellip;<\/p>\n","protected":false},"author":181,"featured_media":909,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[44,390,121],"class_list":["post-14498","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular-js","tag-jasmine","tag-karma","tag-testing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-08-26T09:15:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matthew Brown\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matthew Brown\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\"},\"author\":{\"name\":\"Matthew Brown\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/aa3984d95c5c2926686c428027e8fbd0\"},\"headline\":\"AngularJS Unit Testing With Karma and Jasmine\",\"datePublished\":\"2016-08-26T09:15:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\"},\"wordCount\":1776,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"keywords\":[\"Jasmine\",\"Karma\",\"Testing\"],\"articleSection\":[\"Angular.js\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\",\"name\":\"AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"datePublished\":\"2016-08-26T09:15:06+00:00\",\"description\":\"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Angular.js\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/angular-js\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"AngularJS Unit Testing With Karma and Jasmine\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/aa3984d95c5c2926686c428027e8fbd0\",\"name\":\"Matthew Brown\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e69105b554032a703d8f21c4145672cca61a2dc0239436785b8de9f3e4f392d0?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e69105b554032a703d8f21c4145672cca61a2dc0239436785b8de9f3e4f392d0?s=96&d=mm&r=g\",\"caption\":\"Matthew Brown\"},\"description\":\"He is a web application developer with experience in a wide variety of fields such as agriculture, finance and freight. He's a JavaScript enthusiast and enjoy learning all new technologies. When he's not coding he's enjoying the Kansas City lifestyle with his wife and three dogs and he's currently learning how to play the guitar!\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/matthew-brown\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026","description":"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/","og_locale":"en_US","og_type":"article","og_title":"AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026","og_description":"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects","og_url":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2016-08-26T09:15:06+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","type":"image\/jpeg"}],"author":"Matthew Brown","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Matthew Brown","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/"},"author":{"name":"Matthew Brown","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/aa3984d95c5c2926686c428027e8fbd0"},"headline":"AngularJS Unit Testing With Karma and Jasmine","datePublished":"2016-08-26T09:15:06+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/"},"wordCount":1776,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","keywords":["Jasmine","Karma","Testing"],"articleSection":["Angular.js"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/","url":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/","name":"AngularJS Unit Testing With Karma and Jasmine - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","datePublished":"2016-08-26T09:15:06+00:00","description":"One of the benefits of using AngularJS is that it is designed with testability in mind. Having integrated unit testing can help prevent bugs as projects","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/angularjs-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/javascript\/angular-js\/angularjs-unit-testing-karma-jasmine\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JavaScript","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/"},{"@type":"ListItem","position":3,"name":"Angular.js","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/angular-js\/"},{"@type":"ListItem","position":4,"name":"AngularJS Unit Testing With Karma and Jasmine"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/aa3984d95c5c2926686c428027e8fbd0","name":"Matthew Brown","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e69105b554032a703d8f21c4145672cca61a2dc0239436785b8de9f3e4f392d0?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e69105b554032a703d8f21c4145672cca61a2dc0239436785b8de9f3e4f392d0?s=96&d=mm&r=g","caption":"Matthew Brown"},"description":"He is a web application developer with experience in a wide variety of fields such as agriculture, finance and freight. He's a JavaScript enthusiast and enjoy learning all new technologies. When he's not coding he's enjoying the Kansas City lifestyle with his wife and three dogs and he's currently learning how to play the guitar!","url":"https:\/\/www.webcodegeeks.com\/author\/matthew-brown\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/181"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=14498"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/14498\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/909"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=14498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=14498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=14498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}