Создание модульного теста с жасмином и получение объекта в качестве моего второго вызова.Как правильно вызвать функцию? - PullRequest
0 голосов
/ 27 ноября 2018

Я очень новичок в кодировании, поэтому, пожалуйста, потерпите меня.

Я пытаюсь написать тест для этой функции:

redirect() {
        if (!this.userInfo || !this.userInfo.userId) {
            const originalPath = this.$location.path();
            if (originalPath === '/') {
                this.$location.path('/login');
            } else {
                this.$location.path('/login').search('redirect', originalPath);
            }
            return;
        }

Это мой макет:

beforeEach(() => {
        mocks = {path: function () {return '/login';},
        search: function() {return 'redirect', 'fakepath'}};
        ctrl = new BxIndex(mocks);
    });

Это мой тест:

spyOn(ctrl.$location, 'path').and.returnValue(mocks);
spyOn(ctrl.$location, 'search').and.callThrough();
ctrl.redirect();
expect(ctrl.$location.search).toHaveBeenCalledWith('redirect', 'fakepath');

Сбой, потому что второй вызов является объектом:

Expected spy search to have been called with [ 'redirect', 'fakepath' ] but actual calls were [ 'redirect', Object({ path: spy on path, search: spy on search }) ].

1 Ответ

0 голосов
/ 28 ноября 2018

Простой ответ, чтобы обойти проблему с этим конкретным тестом, состоит в том, чтобы изменить эту строку:

//spyOn(ctrl.$location, 'path').and.returnValue(mocks);
spyOn(ctrl.$location, 'path').and.returnValue('fakepath');

Редактировать : Просмотр тестируемого кодапохоже, ctrl.$location.path возвращает разные результаты в зависимости от того, как он вызывается.Если он вызывается без параметров, он возвращает строку.Если он вызывается со строкой в ​​качестве параметра, то он возвращает сам объект ctrl.$location.Предполагая, что я прав в этом, есть два варианта ...

Первый вариант - просто настроить ваш объект ctrl для теста, чтобы ctrl.$location.path не нуждался в мошенничестве (шпионить) вообще, если это возможно.

Второй вариант заключается в реализации логики двойного возврата в вашем шпионе с использованием callFake:

spyOn(ctrl.$location, 'path').and.callFake(function(arg) {
    if (typeof arg == "string") {
        return ctrl.$location;
    } else {
        return "fakepath";
    }
});

End Edit

Но я думаю, что вам не хватает некоторых деталей о том, как работают функции spyOn, поэтому я немного подробнее расскажу!

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

Например, допустим, у меня есть этот простой объект, foo.У него есть функция с именем sayHello, которая вызывает другую функцию с именем send, которая отправляет сообщение по сети Бобу.Если сообщение успешно отправлено, счетчик messagesToBob увеличивается на единицу, в противном случае он остается прежним.(send возвращает true, если это сработало, или false, если это не сработало).

// Begin contrived example!
var foo = {
    messagesToBob: 0,
    sayHello: function() {
        if (this.send()) {
            this.messagesToBob += 1;
        }
    },
    send: function() {
        network.send("Bob", "Hello");
    }
};

Теперь я хочу это проверить, но, очевидно, я не хочу отправлять Бобу кучу сообщенийво время моих тестов.И вот тут-то и появляется шпион.

spyOn(foo, "send");

По сути, это берет функцию foo.send и заменяет ее пустой функцией (я думаю, она только что вернула undefined).

Если я хочу проверить счетчик foo при успешном запуске, я могу сделать возвращение шпиона «отправка» истинным:

spyOn(foo, "send").and.returnValue(true);
foo.sayHello();

expect(foo.messagesToBob).to.equal(1);

Если я хочу проверить, что не *Приращение 1051 * при неудачной отправке, я могу сделать так, чтобы шпион "send" возвращал false.

В любом из этих случаев я также мог проверить состояние самой функции шпиона, используя expect(...).toHaveBeenCalled() или * 1055.* (или любые другие функции, доступные для вашей конкретной среды / среды тестирования).

В любом случае, надеюсь, это поможет!Функции вашего «фиктивного» объекта не должны возвращать значение в этом примере (при условии, что вам вообще нужен этот объект), потому что эти функции все равно заменяются шпионами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...