#javascript #angularjs #jasmine #karma-jasmine
#javascript #angularjs #jasmine #карма-жасмин
Вопрос:
Я пытаюсь написать простой тест jasmine для тестирования, который $scope.users
устанавливается при обратном Users.find
вызове . В моем последнем тесте ниже scope.users
значение не определено, поэтому тест завершается неудачно.
Как я могу проверить, что scope.users
она установлена, чтобы мой тест прошел?
контроллер
angular.module('web').controller('CardsCtrl',function($scope, $http, Users){
/**
* Get all users on page load
*/
Users.find(function(users) {
$scope.users = users;
});
Служба пользователей
(function(window, angular, undefined) {'use strict';
var urlBase = "http://localhost:3333/api";
var module = angular.module("services", ['ngResource']);
module.factory(
"Users",
['LoopBackResource', 'LoopBackAuth', '$injector', function(Resource, LoopBackAuth, $injector) {
var R = Resource(
urlBase "/users/:id",
{ 'id': '@id' },
{
"find": {
url: urlBase "/users",
method: "GET",
isArray: true,
},
}
);
return R;
}]);
спецификация
describe('CardsCtrl', function() {
var scope, ctrl, users;
beforeEach(module('web'));
beforeEach(inject(function($rootScope, $controller, Users) {
scope = $rootScope.$new();
users = Users;
spyOn(users, 'find');
ctrl = $controller('CardsCtrl', {$scope: scope, Users: users});
}));
describe('the cards controller being instantiated', function() {
it('should be defined', function() {
expect(ctrl).toBeDefined();
});
it('tracks that the spy was called', function() {
expect(users.find).toHaveBeenCalled();
});
it('fetches user data and assigns it to scope.users', function(done) {
console.log('users= ' scope.users); // <-- THIS RETURNS UNDEFINED
expect(scope.users).toBeTruthy();
});
});
});
Комментарии:
1. Можете ли вы опубликовать код, связанный с пользовательской службой?
2. Это уже есть. Это средний фрагмент кода. Это в значительной степени просто сервис, обернутый вокруг ресурса.
3. Я считаю, что вам нужно использовать
$httpBackend
для имитации ответа, который вернет ваш сервис.
Ответ №1:
Вам нужно вызвать .andCallThrough()
шпиона и использовать $httpBackend
для имитации http-ответа:
describe('CardsCtrl', function() {
var scope, ctrl, users, httpBackend;
beforeEach(module('web'));
beforeEach(inject(function($rootScope, $controller, Users, $httpBackend) {
scope = $rootScope.$new();
users = Users;
spyOn(users, 'find').andCallThrough();
httpBackend = $httpBackend;
httpBackend.expectGET(urlBase '/users').respond(200, ['user1', 'user2']);
ctrl = $controller('CardsCtrl', {$scope: scope, Users: users});
}));
afterEach(function() {
httpBackend.verifyNoOutstandingExpectation();
httpBackend.verifyNoOutstandingRequest();
});
describe('the cards controller being instantiated', function() {
... // other tests
it('fetches user data and assigns it to scope.users', function(done) {
httpBackend.flush();
expect(scope.users).toBeTruthy();
});
});
});
Макет $httpBackend
предоставляется службой ngMock, поэтому вам необходимо включить angular-mock.js
для запуска теста.
Комментарии:
2. Модульные тесты @Catfish должны выполняться как можно быстрее и не должны зависеть от доступности внешних служб, поэтому вы не хотите делать реальные http-запросы в модульных тестах. Для этой цели создается $httpBackend . Более подробную информацию см. в документах angular: docs.angularjs.org/api/ngMock/service /$httpBackend