Використання Жасмін для шпигування функції без об'єкта


154

Я новачок в Жасмін і тільки почав його використовувати. У мене є js-файл бібліотеки з великою кількістю функцій, які не пов'язані з жодним об'єктом (тобто є глобальним). Як мені почати шпигувати за цими функціями?

Я спробував використовувати вікно / документ як об’єкт, але шпигун не працював, навіть якщо функція викликалася. Я також спробував упакувати його в підроблений об'єкт наступним чином:

var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");

і тест с

expect(fakeElement.fakeMethod).toHaveBeenCalled();

Це не працює, як і шпигун не працював

Відповіді:


155

Якщо ви визначаєте свою функцію:

function test() {};

Тоді це еквівалентно:

window.test = function() {}  /* (in the browser) */

Так spyOn(window, 'test')має працювати.

Якщо це не так, ви також маєте можливість:

test = jasmine.createSpy();

Якщо жоден із них не працює, з вашим налаштуванням відбувається щось інше.

Я не думаю, що ваша fakeElementтехніка працює через те, що відбувається за лаштунками. Оригінальний globalMethod все ще вказує на той самий код. Шпигунство це проксі, але лише в контексті об'єкта. Якщо ви можете отримати свій тестовий код, щоб зателефонувати через fakeElement, він би спрацював, але тоді ви зможете відмовитися від глобальних fns.


2
Це спрацювало! Я думаю, що помилка, яку я робив раніше, полягала в тому, що я викликав шпигун методом () замість методу. Дякую!
Четтер Гуммін

3
У мене виникли проблеми із використанням spyOn (вікно, "тест") із використанням chutzpah для запуску тестів як частини нашої автоматизації через те, що "вікно" не було призначено. Використовуючи jasmine.createSpy () обійшов це.
Хеннерс

7
jasmine.createSpy () прекрасно працював для мене. Дякую!
dplass

1
Раніше test = jasmine.createSpy();шпигували за кутовими, $anchroScrollчудово працювали
Едгар Мартінес

1
Чомусь я не можу отримати жодного способу роботи, але це цілком можливо, що це тому, що я намагаюся знущатися над існуючою функцією вікна; $window.open(url, '_blank');з наміром відкрити нову вкладку (або вікно залежно від налаштування браузера). Як я маю намір переконатися, що вона викликає цю функцію та перевіряє, що вона переходить до потрібної URL-адреси незалежно від браузера?
CSS

71

Користувачі TypeScript:

Я знаю, що ОП запитав про javascript, але для тих користувачів TypeScript, які стикаються з цим, які хочуть шпигувати за імпортованою функцією, ось що ви можете зробити.

У тестовому файлі перетворіть імпорт функції з цього:

import {foo} from '../foo_functions';

x = foo(y);

До цього:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

Тоді ви можете шпигувати FooFunctions.foo:)

spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

3
Дякуємо за підказку TypeScript Має бути однаково для ES6 / Babel, але я цього не пробував.
hgoebl

1
Здається, він працює лише в тому випадку, якщо функція явно викликає псевдонім FooFunctions . У мене є функціональний рядок (), який є заводським поверненням baz () і хочу перевірити, що baz () викликає foo (). Цей метод, здається, не працює в цьому сценарії.
Річард Матсен

4
Це спрацює, якщо псевдонім взято всередині foo_functions, export const FooFunctions = { bar, foo }; а імпорт у тесті стає. import { FooFunctions } from '../foo_functions'. Однак псевдонім все одно повинен бути явно використаний у приватній реалізації foo_functions для роботи шпигуна. const result = FooFunctions.foo(params)// шпигунські звіти виклику const result = foo(params)// шпигунські звіти не дзвонять
Річард Матсен

2
Працював як шарм! Дякую, ти врятував мені багато часу!
SrAxi

1
Це більше не працюєError: <spyOn> : parseCookie is not declared writable or has no setter
Ling Vu

42

Є 2 альтернативи, які я використовую (для жасмину 2)

Цей не зовсім явний, оскільки, здається, функція насправді підробка.

test = createSpy().and.callFake(test); 

Другий більш багатослівний, більш чіткий і "чистіший":

test = createSpy('testSpy', test).and.callThrough();

-> вихідний код жасмину, щоб побачити другий аргумент


Це має трохи більше сенсу і розбиває його досить далеко, щоб дублювати з успіхом. +1 від мене. Спасибі, C§
CSS

9

Дуже простий спосіб:

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

1
import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

Це працювало для мене.


4
Будь ласка, додайте пояснення до своєї відповіді, код сам по собі не є таким корисним для людини, яка задає питання, якщо вони не можуть зрозуміти, що відбувається.
chevybow

0

Моя відповідь трохи відрізняється від @FlavorScape тим, що в імпортованому модулі у мене була одна (експорт за замовчуванням), я зробив наступне:

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.