1
votes

I am trying to test my AngularJS controller using Jasmine with Karma. When I try the documented procedure for configuring a controller test, the $scope is not being created. Actually it looks like the before is not executing at all.

Here is my controller declaration:

angular.module("myApp", ["ngCookies"])
       .controller("myCtrl", function($scope, $window, $location, MyService, 
                   $timeout, $log, $cookies, $q) {

My test looks like this:

describe("MyController test", function() {
var $scope;

beforeEach(
    module("myApp", ["ngCookies"]));
beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new(); // It looks like this is never called
    scope =$scope;
    $controller("myCtrl", {$scope: $scope});
}));
it("Checks the state of various units", function() {

    ...
});

It looks like the beforeEach stuff is never called. I presume I need to inject the rest of my properties into the controller, but if so, I am not sure how.

This is the error in the Test Run log

FAILED MyController test Checks myFunction starting from blank state
Error: [$injector:modulerr] Failed to instantiate module ngCookies due to:
Error: [ng:areq] Argument 'fn' is not a function, got string
http://errors.angularjs.org/1.3.14/ng/areqp0=fn&p1=not%20a%20function%2C%20got%20string
1
I'm seeing something very similar. In my case, part of the cause is that inject() is throwing an exception (before calling the callback) that "Module 'angulartics' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument." I'm passing angularitics in the same fashion that you're passing ngCookies. And I'm sure I've included it, just maybe in the wrong place? Hoping whatever solution is proposed here can help me, too!Timothy Johns

1 Answers

1
votes

My initial problem that I mentioned in the comment to your question was that I was attempting to include the non-minimized version of angulartics.js, and yet there is no such thing. Changing angulartics.js to angulartics.min.js solved that particular problem for me.

So I fixed that, and then got the same "Argument 'fn' is not function" error message that you do.

I realized that both of our code was creating a new module in the call to module(), rather than retrieving the existing ("myApp") module, which is different from the example code.

I then changed my beforeEach() code from:

module('Sheets', ['ngResource', 'angulartics', 'angulartics.google.analytics']);

to

module('Sheets');

and now the callback I pass to inject is indeed called.

Hypothetically, you could try changing:

beforeEach(module("myApp", ["ngCookies"]));

to

beforeEach(module("myApp"));

...and see if that gets it any further.

That's still just cargo-cult programming on my part, and I have no idea why it worked, so I have some more learning to do before I feel right about it. If you (or anyone else) can provide the reason why retrieving an existing module vs. creating a new one is relevant, there's certainly an answer or comment upvote in it for you!