0

I am having trouble calling through to the actual implementation and I am getting this error:

TypeError: undefined is not an object (evaluating 'GitUser.GetGitUser('test').then') ...

Here are my codes:

app.controller('HomeController', ['$scope', 'GitUser', function ($scope, GitUser) {
    $scope.name = "user";

    GitUser.GetGitUser('test').then(function (data) {
        console.log(data);
        if (data) {
            $scope.name = data;
        }
    });
}]);
app.factory('GitUser', function ($http) {
    return {
        GetGitUser: function (username) {
            return $http.get('https://api.github.com/users/' + username)
            .then(function success(response) {
                return response.data.login;
            });
        }
    };
});

Here is my unit test:

describe('HomeController Unit Test', function () {
    var $controllerConstructor, scope;

    beforeEach(module("AngularApp"));

    beforeEach(inject(function ($controller, $rootScope) {
        $controllerConstructor = $controller;
        scope = $rootScope.$new();
    }));

    it('should test if scope.name is test', function () {
        // Act
        GitUser = {
            GetGitUser: function () { }
        };

        spyOn(GitUser, "GetGitUser").and.callThrough();

        GitUser.GetGitUser();

        $controllerConstructor('HomeController', {
            '$scope': scope,
            'GitUser': GitUser
        })

        // Assert
        expect(GitUser.GetGitUser).toHaveBeenCalled();
        expect(scope.name).toBe('test');
    });
});
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Ron T
  • 397
  • 1
  • 4
  • 22

2 Answers2

2

The problem is a bit more complex than just a missing inject ... Here's an adjusted test:

https://plnkr.co/edit/ZMr0J4jmLPtDXKpRvGBm?p=preview

There are a few problems: 1) you are testing a function that returns a promise - so you need to also mock it that way (by using return $q.when(..) for example).

2) you are trying to test code that happens when your controller is created - the

GitUser.GetGitUser('test').then(function (data) {
        console.log(data);
        if (data) {
            $scope.name = data;
        }
    });

should be wrapped in a function instead:

function init() {
 GitUser.GetGitUser('test').then(function (data) {
        console.log(data);
        if (data) {
            $scope.name = data;
        }
    });
}

and then make that available on your scope:

scope.init= init;

Then in your test call the function and verify your assertions. If you don't wrap it in a function it won't be testable.

Also - the mocking and the callThrough thing ... as you are testing the controller (and not the service) you can use callFake instead - the callFake function can return a Promise with a value (the one that you want to verify later) - then you can ensure that the controller part of the puzzle works.

  var name = 'test';
    // instead of trying to mock GitUser you can just callFake and be sure to return a promise
    spyOn(GitUser, "GetGitUser").and.callFake(function() {
      return $q.when(name);
    });

I hope this all makes sense - the plunker should make things clear - I will add some more comments there.

Birgit Martinelle
  • 1,869
  • 1
  • 12
  • 9
  • Awesome, this makes a lot of sense! Thank you, will definitely try this out when I have access to the project. I was using the callThrough so I can get the actual login username to see if it exists. Am I able to do that testing the controller or would I have to create a unit test for the service? @Birgit Martinelle – Ron T Jan 14 '17 at 07:52
  • You should create a separate test for your service to verify that. For that test you'll want to use $httpBackend to mock the http call (if you google $httpBackend you will see some examples. here's one: http://www.bradoncode.com/blog/2015/06/26/unit-testing-http-ngmock-fundamentals/ – Birgit Martinelle Jan 14 '17 at 13:14
0

I think you just miss something here

beforeEach(inject(function ($controller, $rootScope, _GitUser) {
    $controllerConstructor = $controller;
    scope = $rootScope.$new();
    GitUser = _GitUser;
}));
digit
  • 4,479
  • 3
  • 24
  • 43