раскрытие шаблона модуля и области видимости переменной -> открытый объект не определен после возврата асинхронного вызова

0

У меня есть угловой контроллер, который, похоже, работает нормально. Я могу консольно зарегистрировать переменную пользователя внутри вызова службы и содержать правильные данные. Однако в моем тесте я могу консоль регистрировать контроллер и проверять, есть ли у него объект пользователя, но он пуст. Кажется, что initialize пытается сохранить переменную после уничтожения локальной области, но это очень странно, поскольку у меня есть другой контроллер и тест, написанный точно так же, как и работа.

Я повторял это в течение двух дней, поэтому, если у кого-нибудь есть какие-либо выводы, я был бы очень благодарен.

function DetailAccountController (accountsService) {
    'use strict';

    var user = {};

    initialize();

    return {
        user: user
    };

    /**
     * Initialize the controller,
     * & fetch detail for a single user.
     */
    function initialize () {
        // If the service is available, then fetch the user
        accountsService && accountsService.getById('').then(function (res) {
            user = res;
        });

    }
}

и тест на жасмин:

describe('DetailAccountController', function () {
    var ctrl = require('./detail-account-controller'),
        data = [{
            "email": "[email protected]",
            "voornaam": "Mr Fake0",
            "tussenvoegsel": "van0",
            "achternaam": "User0",
            "straat": "Mt Lincolnweg0",
            "huisnr": 0,
            "huisnr_toev": 0,
            "postcode": "0LW",
            "telefoonr": "0200000000",
            "mobielnr": "0680000000",
            "plaats": "Amsterdam",
            "id": "00000000"
        }],
        accountsServiceMock,
        $rootScope,
        $q;

    beforeEach(inject(function (_$q_, _$rootScope_) {
        $q = _$q_;
        $rootScope = _$rootScope_;

        accountsServiceMock = {
            getById: function () {}
        };

    }));

    it('should call the getById method at least once', function () {

        spyOn(accountsServiceMock, 'getById').and.returnValue($q.defer().promise);
        ctrl.call({}, accountsServiceMock);

        expect(accountsServiceMock.getById.calls.any()).toBe(true);
        expect(accountsServiceMock.getById.calls.count()).toBe(1);
    });

    it('should populate user data in the model', function () {
        var deferred = $q.defer();
        deferred.resolve(data);
        spyOn(accountsServiceMock, 'getById').and.returnValue(deferred.promise);

        var vm = ctrl.call({}, accountsServiceMock);
        $rootScope.$apply();

        expect(vm.user).toEqual(data);
    });
});

Обновленное решение для любопытных

function DetailAccountController (accountsService) {
    'use strict';
    var self = this;
    self.user = null;

    initialize();

    return self;

    /**
     * Initialize the controller,
     * & fetch detail for a single user.
     */
    function initialize () {
        accountsService && accountsService.getById('').then(function (res) {
            self.user = res;
        });
    }
}
Теги:
asynchronous
jasmine
revealing-module-pattern

1 ответ

0
Лучший ответ

user = res влияет на локальную переменную и не имеет ничего общего с возвращенным объектом.

Это должно быть либо

    accountsService && accountsService.getById('').then(function (res) {
        angular.extend(user, res);
    });

или

var obj = {
    user: {}
};

initialize();

return obj;

function initialize () {
    accountsService && accountsService.getById('').then(function (res) {
        obj.user = res;
    });

}
  • 0
    Спасибо за ответ @estus. Мое понимание шаблона раскрывающегося модуля состоит в том, что функция модуля может обращаться к переменным внутри области действия функции. Я прав, что это не работает из-за асинхронной функции?
  • 0
    Да, раскрытие модуля не является проблемой, потому что новый объект назначается user после того, как переменная уже была возвращена. Модульный тест является синхронным, но приоритет остается прежним.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню