Как тестировать контроллер, который получает данные от объекта обещания

У меня есть контроллер, который получает данные от объекта обещания.

Контроллер выглядит так:

MyApp.controller("BookListController", ["$scope", "BookListModel","LibraryService", function($scope, BookListModel, LibraryService) {
    LibraryService.getLibraryData().then(function(result) {
        $scope.books = BookListModel.createBookList(result.bookList.data, result.authorList.data, result.publisherList.data);
    });
}]);

Это моя фабрика, которая получает данные от службы REST.

MyApp.factory("LibraryService", function($http, $q) {
    var service = {};
    var libraryDataPromise = $q.defer();

    $q.all({
        books : $http.get("http://localhost:8080/library/service/books"),
        authors : $http.get("http://localhost:8080/library/service/authors"),
        publishers : $http.get("http://localhost:8080/library/service/publishers")
    }).then(function(response) {
        libraryDataPromise.resolve({
            bookList : response.books,
            authorList : response.authors,
            publisherList : response.publishers
        });
    });

    service.getLibraryData = function() {
        return libraryDataPromise.promise;
    }

    return service;
});

Хорошо, это все. Теперь пришло время показать мой тест, который я написал.

describe("Book_App Controllers", function() {

describe("BookListController Test", function() {
    var BookListModelMock, LibraryServiceMock, scope = {}, controller
        ,deferred, promise;

    beforeEach(function() {
        module("MyApp");
        BookListModelMock = new function() {
            this.createBookList = function(a, b, c) {
                return [{},{},{}];
            };
        };
    });

    beforeEach(inject(function($rootScope, $controller ) {
        scope = $rootScope.$new();
        controller = $controller("BookListController",
            {$scope : scope, BookListModel : BookListModelMock});
    }));

    beforeEach(inject(function($q) {
        deferred = $q.defer();
        promise = deferred.promise;
        deferred.resolve([
            { data : [{}, {}, {}]}
        ])

        LibraryServiceMock = function() {
            var service = {};

            service.getLibraryData = function() {
                return promise;
            }
        };
    }));

    it("should contains three books", inject(function($rootScope) {
        $rootScope.$apply();
        expect(scope.books.length).toBe(3);
    }));
});

});

Когда я запускаю тест, Jasmine throw: Ошибка: Неожиданный запрос: GET http://localhost:8080/library/service/books Больше не ожидается запрос

Я знаю, что означает эта проблема, но я не знаю, как ее решить. Должен ли я издеваться над $http? Я читал, как тестирование обещает и откладывает, но в руководстве описывается, как тестирование функций, которые содержат операции $q, и не описывается, как тестирование функций, которые зависят от функций, которые содержат операции $q

1 ответ

Решение

Ваш LibraryServiceMock не используется. Вам нужно создать макет перед созданием контроллера, а затем использовать его так же, как вы предоставляете BookListModelMock для нового контроллера.

Когда вы пишете свои тесты LibraryService, вы можете использовать $httpBackend.expect() для макетирования запросов: https://docs.angularjs.org/api/ngMock/service/$ httpBackend

Другие вопросы по тегам