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


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.