× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

Getting an [x]Provider error when unit testing AngularJS with Jasmine and Karma

Michael Perrenoud
Feb 22, 2015
<p>This is a really common error to encounter. It can be one of two things in general:</p> <ol> <li>The file isn't being loaded in your <code>karma.conf</code> file; or</li> <li>The module it lives in isn't a dependency on the module you're testing.</li> </ol> <p>The first one is the easiest to fix. In your <code>karma.conf</code> file you should have a section that looks something like this:</p> <pre><code class="language-javascript">files: [ // simple pattern to load the needed testfiles // equal to {pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true} 'test/unit/*.spec.js', // here you'd have other files that matter for testing // files like AngularJS and your modules, services, factories, and more 'lib/.../angular.js', 'lib/.../angular-mocks.js', 'lib/.../angular-resource.js', 'app/.../core.module.js', 'app/.../users.module.js', 'app/.../other.module.js', 'app/.../other.controllers.js' ], </code></pre> <p>Now, let's make the assumption that in the <code>other.controllers.js</code> file there is a controller named <code>OtherController</code>. Let's say that controller is defined like this:</p> <pre><code class="language-javascript">var mod = angular.module('other'); mod.controller('OtherController', ['$scope', 'OtherService', 'UsersService', function($scope, OtherService, UsersService) { // here would be all the code for the controller }</code></pre> <p>Looks simple and harmless enough. Now let's take a look at the <code>other.module.js</code> file where the <code>other</code> module is defined:</p> <pre><code class="language-javascript">// raw angular var mod = angular.module('other', []); // MEAN.JS ApplicationConfiguration.registerModule('other');</code></pre> <p>Looks pretty good! Now let's look at the test spec that's failing, specifically where we load the module we're testing:</p> <pre><code class="language-javascript">describe('Other module tests', function() { beforeEach(module('other')); it('should be able to create the controller', inject(function(...) { ... })); }); </code></pre> <p>Clearly I've left a lot out of this test, I want to focus on the line that says <code>beforeEach(module('other'))</code> because that's what's going to be causing the problems. Now, back to the problem at hand. This setup is going to throw an error complaining about the <code>UsersServiceProvider</code>.</p> <p>The first problem is that the file that includes that service isn't loaded in our <code>karma.conf files</code> section. That's easy enough, let's add it:</p> <pre><code class="language-javascript">files: [ // simple pattern to load the needed testfiles // equal to {pattern: 'test/unit/*.spec.js', watched: true, served: true, included: true} 'test/unit/*.spec.js', // here you'd have other files that matter for testing // files like AngularJS and your modules, services, factories, and more 'lib/.../angular.js', 'lib/.../angular-mocks.js', 'lib/.../angular-resource.js', 'app/.../core.module.js', 'app/.../users.module.js', 'app/.../other.module.js', 'app/.../users.service.js', 'app/.../other.controllers.js' ], </code></pre> <p>However, there is another ensuing problem. When loading the <code>other</code> module, <code>ngMock</code> doesn't know to load <code>users</code>. This means that even after including the file it's still going to fail. To fix the ensuing error that has now prepared you to throw you machine out the window is easily fixed. Just change the module definition:</p> <pre><code class="language-javascript">// raw angular var mod = angular.module('other', ['users']); // MEAN.JS ApplicationConfiguration.registerModule('other', ['users']);</code></pre> <p> And BAM, you're in business! Until next time, happy coding!</p>
comments powered by Disqus