<commit_before># AngularJS Unit Testing

Unit testing, as the name implies, is about testing individual units of code.

Angular is written with testability in mind and come with [dependency injection](https://docs.angularjs.org/guide/di)
built in. DI helps us to achieve decoupling and therefore to test our objects in isolation.

Angular provides [ngMock](https://docs.angularjs.org/api/ngMock) to inject and mock services into unit tests. And one
of the most useful parts of `ngMock`  is `$httpBackend` which lets us mock XHR requests.

## Table of Contents

* [Karma](#karma)
  * [Templates](#templates)
* [Mocking](#mocking)
* [Spying](#spying)
* [Testing](#testing)
  * [Controllers](#controllers)
  * [Services](#services)
  * [Directives](#directives)
  * [Providers](#providers)

## Karma

[Karma](http://karma-runner.github.io/0.12/index.html) is a test runner which allow us to execute tests in multiple browsers.

After [installing](https://karma-runner.github.io/0.12/intro/installation.html) it we need to crete a configuration
file running `karma init`.

And set the list of files that need to be loaded in the browser.

```js
module.exports = function(config) {
  config.set({
    files: [
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'src/**/*.js'
    ]
  });
};
```

### Templates

When testing directives we need to set up Karma to serve our templates.

And for that we use a preprocessor to convert HTML into JS string.
[ng-html2js](https://github.com/karma-runner/karma-ng-html2js-preprocessor) creates a "templates" module and put the HTML
 into the `$templateCache`.

We need to add some lines to the Karma configuration.

```js
module.exports = function(config) {
  config.set({
    preprocessors: {
      'src/**/*.html': ['ng-html2js']
    },

    files: [
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'src/**/*.js',
      'src/**/*.html',
    ],

    ngHtml2JsPreprocessor: {
      stripPrefix: 'src/',
      moduleName: 'templates'
    }
  });
};
```

## Mocking

To test the functionality of a piece of code in isolation we need to mock any dependency.

A service (service, factory, value, constant, or provider) is the most common type of dependency in Angular applications
and they are defined via providers.

The [injector](https://docs.angularjs.org/api/auto/service/$injector) retrieves object instances as defined by provider.
So there are at least two ways we can mock our services.

### Using $provide

We provide our own implementation in a `beforeEach` Jasmine block.

```js
var myService;
beforeEach(module(function($provide) {
  myService = {
    syncCall: function() {},
    asyncCall: function() {}
  };
  $provide.value('myService', myService);
}));
```

### Creating a provider mock

We create the implementation in a separate `my-service.service.mock.coffee` file so we can reuse it.

```js
angular.module('myServiceMock', [])
  .provider('myService', function() {
    this.$get = function() {
      return {
        syncCall: function() {},
        asyncCall: function() {}
      };
    };
  });
```

And later we load the mocked module in a `beforeEach` Jasmine block inside of our test suite.

```js
beforeEach(module('myServiceMock'));

var myService;
beforeEach(inject(function(_myService_) {
  myService = _myService_;
}));
```

It's good to **load the mocked modules after** the module we are testing to be sure the mock overrides the actual implementation.

## Spying<commit_msg>Add about and coverage sections to the guide<commit_after># AngularJS Unit Testing

Unit testing, as the name implies, is about testing individual units of code.

## About

This guide tries to show a few patterns and guidelines to help us with unit testing Angular applications after setting
some minimum configuration.

A more readable version was [published on Airpair](https://www.airpair.com/angularjs/posts/unit-testing-angularjs-applications)
and won the "Best AngularJS post" category of the 2015 Developer Writing Competition.
It has been shared more than 600 times on social media.

This repository contains also a complimentary [example project](example) with 100% test coverage.

## Table of Contents

* [Configuring](#configuring)
  * [ngMock](#ngmock)
  * [Karma](#karma)
    * [Templates](#templates)
    * [Coverage](#coverage)
* [Mocking](#mocking)
  * [Using $provide](#using-provide)
  * [Creating a provider mock](#creating-a-provider-mock)
* [Spying](#spying)
* [Testing](#testing)
  * [Controllers](#controllers)
  * [Services](#services)
  * [Directives](#directives)
  * [Providers](#providers)

## Configuring

### ngMock

Angular provides [ngMock](https://docs.angularjs.org/api/ngMock) to inject and mock services into unit tests. And one
of the most useful parts of `ngMock`  is `$httpBackend` which lets us mock XHR requests.

```
$ npm install angular-mocks --save-dev
```

### Karma

[Karma](http://karma-runner.github.io/) is a test runner which allow us to execute tests in multiple browsers.

```
# Install Karma:
$ npm install karma --save-dev

# Install plugins that our project needs:
$ npm install karma-jasmine jasmine-core karma-chrome-launcher --save-dev
```

After installing it we need to crete a configuration
file running `karma init`.

And set the list of files that need to be loaded in the browser.

```js
module.exports = function(config) {
  config.set({
    files: [
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'src/**/*.js'
    ]
  });
};
```

#### Templates

When testing directives we need to set up Karma to serve our templates.

And for that we use a preprocessor to convert HTML into JS string.
[ng-html2js](https://github.com/karma-runner/karma-ng-html2js-preprocessor) creates a "templates" module and put the HTML
 into the `$templateCache`.

 ```
$ npm install karma-ng-html2js-preprocessor --save-dev
```

We need to add some lines to the Karma configuration.

```js
module.exports = function(config) {
  config.set({
    preprocessors: {
      'src/**/*.html': ['ng-html2js']
    },

    files: [
      'node_modules/angular/angular.js',
      'node_modules/angular-mocks/angular-mocks.js',
      'src/**/*.js',
      'src/**/*.html',
    ],

    ngHtml2JsPreprocessor: {
      stripPrefix: 'src/',
      moduleName: 'templates'
    }
  });
};
```

#### Coverage

It's great to identify which parts of our code are lacking test coverage and generate reports with
[Istanbul](https://github.com/gotwarlost/istanbul), that calculates the percentage of code accessed by tests.

```
$ npm install karma karma-coverage --save-dev
```

In the configuration file we need to exclude spec and mock files from the report.

```js
module.exports = function(config) {
  config.set({
    preprocessors: {
      'src/**/!(*.mock|*.spec).js': ['coverage']
    },

    reporters: ['progress', 'coverage'],

    coverageReporter: {
      type : 'html',
      // output coverage reports
      dir : 'coverage/'
    }
  });
};
```

## Mocking

To test the functionality of a piece of code in isolation we need to mock any dependency.

Angular is written with testability in mind and come with [dependency injection](https://docs.angularjs.org/guide/di)
built in, what helps us to achieve decoupling and therefore to test our objects in isolation.

A service (service, factory, value, constant, or provider) is the most common type of dependency in Angular applications
and they are defined via providers.

The [injector](https://docs.angularjs.org/api/auto/service/$injector) retrieves object instances as defined by provider.
So there are at least two ways we can mock our services.

### Using $provide

We provide our own implementation in a `beforeEach` Jasmine block.

```js
var myService;
beforeEach(module(function($provide) {
  myService = {
    syncCall: function() {},
    asyncCall: function() {}
  };
  $provide.value('myService', myService);
}));
```

### Creating a provider mock

We create the implementation in a separate `my-service.service.mock.js` file so we can reuse it.

```js
angular.module('myServiceMock', [])
  .provider('myService', function() {
    this.$get = function() {
      return {
        syncCall: function() {},
        asyncCall: function() {}
      };
    };
  });
```

And later we load the mocked module in a `beforeEach` Jasmine block inside of our test suite.

```js
beforeEach(module('myServiceMock'));

var myService;
beforeEach(inject(function(_myService_) {
  myService = _myService_;
}));
```

It's good to **load the mocked modules after** the module we are testing to be sure the mock overrides the actual implementation.

## Spying
{'fraction_non_alphanumeric': 0.1254443297786951, 'fraction_numerical': 0.0028666437335167984, 'mean_word_length': 3.8455555555555554, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 11, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '37636', 'n_tokens_mistral': 2693, 'n_tokens_neox': 2563, 'n_words': 903}