javascript - לעקוף אובייקט לקריאה בלבד בתוך בדיקת יחידה של jasmine


מישהו יודע איך לעקוף תכונות ופונקציות באובייקטים לקריאה בלבד כמו window או [htmlelement].style?

דוגמת פונקציה שצריך לבדוק:

public static getCSSTransitionEvent(element: HTMLElement): string {
    let transitions = {
        'transition': 'transitionend',
        'OTransition': 'oTransitionEnd',
        'MozTransition': 'transitionend',
        'WebkitTransition': 'webkitTransitionEnd'
    };

    for (let transition in transitions) {
        if (element.style[transition] !== undefined ) {
            return transitions[transition];
        }
    }
    return;
}

איך אני יכול להחליף את התכונה transition ב-element.style כדי לבדוק שהפונקציה מחזירה undefined בסוף?

עוד דוגמה, איך אני בודק את משפט ה-if הזה

function isCryptoAvailable() {
    if (typeof (window.crypto) !== 'undefined' && typeof (window.crypto.getRandomValues) !== 'undefined') {
        return true
    }
    else {
        return false
    }
}

תשובה #1

זה נעשה באמצעות מתארי נכסים. לנכסים לקריאה בלבד יש את תכונת המתאר writable מוגדרת כ- false. כל עוד הם configurable, ניתן להגדירם מחדש עם Object.defineProperty כמו:

 const cryptoDescriptor = Object.getOwnPropertyDescriptor(window, 'crypto');

 afterEach(() => {
   if (origCryptoDescriptor) {
     delete window.crypto;
     Object.defineProperty(window, 'crypto', cryptoDescriptor);
   }
 });

 it('...', () => {
   expect(origCryptoDescriptor).toBeTruthy();
   expect(origCryptoDescriptor.configurable).toBeTruthy();

   const cryptoMock = ...;
   delete window.crypto;
   window.crypto = cryptoMock;
   ...
 });

המתאר צריך להיות מוחזר ב-afterEach כי הוא יתבצע אפילו אם המבחן נכשל. והמבחן ייכשל אם הנכס הוא לא קונפיגורבילי. זה אפשרי בכמה דפדפנים, לכן יש להסיר את המבחן מסוויטת המבחנים בדפדפנים שידועים ככאלה שנכשלו בו.

אותו הדבר נכון לגבי פונקציה שמערבת לא-גלובלים כמו אובייקט HTMLElement, אבל אם אפשר לדמות את האובייקט הזה במלואו במקום לדמות את התכונות שלו, זו האסטרטגיה המועדפת.