Использование Jasmines spyon по частному методу

Можно ли использовать метод Spyon платформы модульного тестирования Jasmine на частных методах классов?

Документация дает этот пример, но может ли это быть гибким для частной функции?

describe("Person", function() {
    it("calls the sayHello() function", function() {
        var fakePerson = new Person();
        spyOn(fakePerson, "sayHello");
        fakePerson.helloSomeone("world");
        expect(fakePerson.sayHello).toHaveBeenCalled();
    });
});

Ответ 1

Просто добавьте общий параметр <any> для функции spyon():

 spyOn<any>(fakePerson, 'sayHello');

Он отлично работает!

Ответ 2

если вы используете Typescript для своих объектов, функция на самом деле не является закрытой.
Все, что вам нужно, это сохранить значение, возвращенное из вызова spyOn, а затем запросить его свойство calls.

В конце этот код должен нормально работать для вас (по крайней мере, он работал для меня):

describe("Person", function() {
    it("calls the sayHello() function", function() {
        var fakePerson = new Person();
        // save the return value:
        var spiedFunction = spyOn<any>(fakePerson, "sayHello");
        fakePerson.helloSomeone("world");
        // query the calls property:
        expect(spiedFunction.calls.any()).toBeFalsy();
    });
});

Ответ 3

Typescript компилируется в javascript, и в javascript каждый метод является публичным. Таким образом, вы можете использовать индексную запись массива для доступа к закрытым методам или файлам, а именно:

Object['private_field']

Ответ 4

Нет причин, по которым вы не можете получить доступ к частной функции вне контекста вашего экземпляра.

Btw, это не хорошая идея, чтобы шпионить за объектами, которые вы хотите проверить. Когда вы проверяете, вызван ли какой-либо конкретный метод в вашем классе, который вы хотите протестировать, он ничего не говорит. Допустим, вы написали тест, и он прошел, через две недели вы рефакторируете некоторые вещи в функции и добавляете ошибку. Таким образом, ваш тест по-прежнему зеленый, потому что вы вызываете функцию. В

Шпионы полезны, когда вы работаете с Dependency Injection, где все внешние зависимости передаются конструктором и не создаются в вашем классе. Поэтому давайте скажем, что у вас есть класс, которому нужен элемент dom. Нормальный, чтобы использовать этот элемент в селекторе jquery. Но как вы хотите проверить, что что-то сделано с этим элементом? Конечно, вы можете добавить его на свои страницы тестов html. Но вы также можете вызвать свой класс, передавая элемент в конструкторе. Таким образом, вы можете использовать шпион, чтобы проверить, взаимодействует ли ваш класс с этим элементом, как вы ожидали.

Ответ 5

В моем случае (машинопись):

jest.spyOn<any, string>(authService, 'isTokenActual')

ИЛИ с поддельным результатом:

jest.spyOn<any, string>(authService, 'isTokenActual').mockImplementation(() => {
  return false;
});

Ответ 6

Если вы хотите проверить частные функции внутри класса, почему бы не добавить конструктор в ваш класс, который сигнализирует о возврате этих частных функций?

Прочитайте это, чтобы понять, что я имею в виду: http://iainjmitchell.com/blog/?p=255

Я использую подобную идею, и до сих пор она отлично работает!

Ответ 7

Допустим, sayHello(text: string) является частным методом. Вы можете использовать следующий код:

// Create a spy on it using "any"
spyOn<any>(fakePerson, 'sayHello').and.callThrough();

// To access the private (or protected) method use [ ] operator:
expect(fakeperson['sayHello']).toHaveBeenCalledWith('your-params-to-sayhello');
  • Создайте шпионский метод с помощью any.
  • Для доступа к закрытому (или защищенному) методу используйте оператор [].