جاوااسکریپت - استفاده از Jasmine برای جاسوسی از یک تابع بدون استفاده از یک شیء


من از Jasmine استفاده میکنم و یک فایل کتابخانه js دارم که شامل تعداد زیادی تابع است که به هیچ شیئی مرتبط نیستند (یعنی سراسری هستند). چطور میتوانم روی این توابع جاسوسی کنم؟

من سعی کردم از window/document به عنوان شیء استفاده کنم، اما جاسوس کار نکرد حتی با اینکه تابع فراخوانی شده بود. همچنین سعی کردم آن را در یک شیء جعلی به صورت زیر بپیچم:

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

و آزمایش با

expect(fakeElement.fakeMethod).toHaveBeenCalled();

این هم کار نمیکند زیرا جاسوس کار نکرد.

پاسخ شماره ۱

اگر در حال تعریف تابع خود هستید:

function test() {};

پس، این معادل است با:

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

پس spyOn(window, 'test') باید کار کند.

اگر اینطور نیست، شما همچنین باید قادر باشید:

test = jasmine.createSpy();

اگر هیچکدام از اینها کار نمیکنند، مشکلی دیگر در تنظیمات شما وجود دارد.

من فکر نمیکنم تکنیک fakeElement شما کار کند به خاطر آنچه که پشت صحنه اتفاق میافتد. متد سراسری اصلی هنوز به همان کد اشاره میکند. کاری که جاسوسی انجام میدهد این است که آن را پروکسی میکند، اما فقط در زمینه یک شیء. اگر بتوانید کد تست خود را وادار کنید از طریق fakeElement فراخوانی شود، کار میکند، اما در این صورت مجبور میشوید از توابع سراسری صرف نظر کنید.

پاسخ شماره ۲

کاربران 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();

پاسخ شماره ۳

دو گزینه وجود دارد که من استفاده میکنم (برای یاسمین ۲)

این یکی چندان صریح نیست زیرا به نظر میرسد که عملکرد در واقع جعلی است.

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

دوم طولانیتر، صریحتر و «پاکتر»:

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

-> کد منبع jasmine برای دیدن آرگومان دوم