2017-01-14 11 views
0

Я новичок в модульном тестировании, поэтому, пожалуйста, со мной. У меня возникли проблемы с вызовом до фактической реализации, и я получаю эту ошибку:Проблема с жасминовыми шпионами звоните через

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

Вот мои коды:

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; 
      }); 
     } 
    }; 
}); 

Вот мой блок тест:

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'); 
    }); 
}); 

Любое предложение или помощь будет здорово! Заранее спасибо!

ответ

2

Проблема является немного более сложным, чем просто отсутствующей Inject ... Вот скорректированный тест:

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

Есть несколько проблем: 1) вы тестируете функцию, которая возвращает обещание, поэтому вам также нужно сделать так, чтобы это было сделано (используя обратное $q.when(..)).

2) вы пытаетесь проверить код, который происходит, когда создается контроллер -

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

должны быть обернуты в функции вместо:

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

, а затем сделать это доступно на вашем Сфера применения:

scope.init= init; 

Затем в вашем тестовом режиме вызовите функцию и подтвердите свой запрос rtions. Если вы не завернете его в функцию, он не будет проверен.

Кроме того - насмешливая и вызывающая вещь ... поскольку вы тестируете контроллер (а не службу), вы можете использовать callFake вместо этого - функция callFake может возвращать Promise со значением (тем, которое вы хотите подтвердите позже) - тогда вы можете убедиться, что часть контроллера работает.

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); 
    }); 

Я надеюсь, что все это имеет смысл - плункер должен прояснить ситуацию - добавлю еще несколько комментариев.

+0

Удивительно, это имеет большой смысл! Спасибо, обязательно попробуем это, когда у меня будет доступ к проекту. Я использовал callThrough, чтобы получить фактическое имя пользователя для входа, чтобы узнать, существует ли он. Могу ли я сделать это тестирование контроллера или мне нужно будет создать единичный тест для службы[email protected] Martinelle –

+0

Вы должны создать отдельный тест для своей службы, чтобы убедиться в этом. Для этого теста вы захотите использовать $ httpBackend, чтобы издеваться над http-вызовом (если вы google $ httpBackend, вы увидите несколько примеров. Вот один из них: http://www.bradoncode.com/blog/2015/06/26/unit -тестирование-HTTP-ngmock-основа / –

0

Я думаю, что вы просто пропустить что-то здесь

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

это дало мне эту ошибку, когда я попробовал это: Ошибка: [$ injector: unpr] Неизвестный поставщик: _GitUserProvider <- _GitUser –

+0

Oh .. Попробуйте удалить подчеркивание? – digit