Skip to content

Instantly share code, notes, and snippets.

@DavidFrahm
Last active March 1, 2017 01:21
Show Gist options
  • Save DavidFrahm/7901902 to your computer and use it in GitHub Desktop.
Save DavidFrahm/7901902 to your computer and use it in GitHub Desktop.
AngularJS: Unit test for HTTP Provider config
/*
* If we assume that the philosophy of a provider is only configuration then it makes more sense in most
* cases to test that "it" is configured. As the "it" in this case is the resulting service, using
* module to do the configuration and then inject to test that the configuration worked seems to make sense.
* The trick to understanding these tests is to realize that the function passed to module() does not get called until inject() does it's thing. So assigning to a closure variable in the module initialization function ensures that the Provider is defined before control passes to the injected function. Then you're free to interact with the Provider's configuration interface. The technique is a little bit broken in that the Provider has already provided it's Service. But, if you can tolerate that limitation it works.
*
* Most of this I learned from https://github.com/angular/angular.js/issues/2274
*
* There are multiple describe() suites and it() tests, just to help us trace what's going on.
* Hopefully, that makes this spec a good learning tool.
*/
describe('myApp Module', function () {
describe('config: with module callback in beforeEach', function () {
var httpProvider;
beforeEach(module('myApp', function ($httpProvider) {
console.log('BEGIN: module callback');
httpProvider = $httpProvider;
console.log('END: module callback');
}));
it('should show that beforeEach module callback is not executed when test does not need module', function () {
console.log('BEGIN: it test - no module');
expect(true).toBeTruthy();
console.log('END: it test - no module');
});
it('should have added authTokenHttpInterceptor as http interceptor (inject calls module callback before run test)', inject(function () {
console.log('BEGIN: it test');
expect(httpProvider.interceptors).toContain('authTokenHttpInterceptor');
console.log('END: it test');
}));
});
describe('config: do everything inside the test', function () {
it('should be able to test provider with module inside it()', function () {
console.log('BEGIN: it test: all-in-it');
var httpProviderIt;
module('myApp', function ($httpProvider) {
console.log('BEGIN: module callback');
httpProviderIt = $httpProvider;
console.log('END: module callback');
});
inject(function () {
console.log('BEGIN: it test - inject');
// Works inside inject()
expect(httpProviderIt.interceptors).toContain('authTokenHttpInterceptor');
console.log('END: it test - inject');
});
// Also works after/outside inject()
expect(httpProviderIt.interceptors).toContain('authTokenHttpInterceptor');
console.log('END: it test: all-in-it');
});
});
});
@spencercarnage
Copy link

A couple line breaks for the text in the /* */ block would do wonders for this gist.

@sheltonial
Copy link

I had the same issue but testing code within the run block. Managed to figure it out: http://stackoverflow.com/a/24949238/2415971

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment