আমি ঠাট্টা পরীক্ষায় লোকালস্টোরের সাথে কীভাবে আচরণ করব?


144

আমি জাস্ট টেস্টগুলিতে "লোকালস্টোরেজ সংজ্ঞায়িত করা হয়নি" যা বুদ্ধিমান হয় তবে আমার বিকল্পগুলি কী? ইটের দেয়াল মারছে।

উত্তর:


141

@ সিডো থেকে দুর্দান্ত সমাধান

যাইহোক, আমরা ES2015 বাক্য গঠন ব্যবহার করেছি এবং আমি অনুভব করেছি যে এটি এইভাবে লিখতে এটি কিছুটা পরিষ্কার।

class LocalStorageMock {
  constructor() {
    this.store = {};
  }

  clear() {
    this.store = {};
  }

  getItem(key) {
    return this.store[key] || null;
  }

  setItem(key, value) {
    this.store[key] = value.toString();
  }

  removeItem(key) {
    delete this.store[key];
  }
};

global.localStorage = new LocalStorageMock;

8
value + ''নাল এবং
অপরিজ্ঞাত

আমি মনে করি যে সর্বশেষতম রসিকতা কেবলমাত্র || nullসে কারণেই আমার পরীক্ষাটি ব্যর্থ হয়েছিল, কারণ আমার পরীক্ষায় আমি ব্যবহার করছিলাম not.toBeDefined()। @ শেইদো সমাধান আবার এটি কাজ করে
jcubic

আমি মনে করি এটি প্রযুক্তিগতভাবে একটি স্টাব :) বিদ্রূপিত
প্রশ্নগুলি

100

এটির সাহায্যে এটি চিত্রিত করেছেন: https://groups.google.com/forum/#!topic/jestjs/9EPhuNWVYTg

নিম্নলিখিত বিষয়বস্তু সহ একটি ফাইল সেটআপ করুন:

var localStorageMock = (function() {
  var store = {};
  return {
    getItem: function(key) {
      return store[key];
    },
    setItem: function(key, value) {
      store[key] = value.toString();
    },
    clear: function() {
      store = {};
    },
    removeItem: function(key) {
      delete store[key];
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

তারপরে আপনি আপনার জেস্ট কনফিগারেশনের অধীনে আপনার প্যাকেজ.জসনে নিম্নলিখিত লাইনটি যুক্ত করুন

"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",


6
দৃশ্যত আপডেট এক সঙ্গে এই প্যারামিটারটি নাম পরিবর্তন এবং এখন এটা বলা হয় "setupTestFrameworkScriptFile"
Grzegorz Pawlik

2
"setupFiles": [...]পাশাপাশি কাজ করে। অ্যারে বিকল্পের সাহায্যে মককে পৃথক ফাইলে আলাদা করার অনুমতি দেয়। উদাহরণস্বরূপ:"setupFiles": ["<rootDir>/__mocks__/localStorageMock.js"]
স্টিগলগার

3
getItemযদি কোনও নির্দিষ্ট কীটির সাথে কোনও ডেটা সেট না করা হয় তবে কোনও ব্রাউজার দ্বারা কী ফিরিয়ে দেওয়া হবে তার ফেরতের মানটি কিছুটা পৃথক হয় । getItem("foo")সেট না করা হলে কল করা উদাহরণস্বরূপ nullএকটি ব্রাউজারে ফিরে আসবে , তবে undefinedএই মক দ্বারা - এটি আমার পরীক্ষাগুলির একটিতে ব্যর্থ হয়ে পড়েছিল। আমার জন্য সহজ সমাধান আসতে ছিল store[key] || nullমধ্যে getItemফাংশন
বেন Broadley

আপনি যদি এমন কিছু করেন তবে এটি কাজ করে নাlocalStorage['test'] = '123'; localStorage.getItem('test')
rob

3
আমি নিম্নলিখিত ত্রুটিটি পাচ্ছি - jest.fn () মান অবশ্যই মক ফাংশন বা স্পাই হতে হবে। কোন ধারনা?
পল ফিৎসগেরাল্ড

55

যদি ক্রিয়েট-রিএ্যাক্ট-অ্যাপ ব্যবহার করা হয় তবে ডকুমেন্টেশনে একটি সহজ এবং সরল সমাধান ব্যাখ্যা করা আছে ।

এটি তৈরি করুন src/setupTests.jsএবং এতে রাখুন:

const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  clear: jest.fn()
};
global.localStorage = localStorageMock;

নীচে একটি মন্তব্যে টম মার্টজ অবদান:

এরপরে আপনি পরীক্ষা করতে পারেন যে আপনার লোকালস্টোরেশনমকের ফাংশনগুলি এমন কিছু করে ব্যবহার করা হয়

expect(localStorage.getItem).toBeCalledWith('token')
// or
expect(localStorage.getItem.mock.calls.length).toBe(1)

আপনার পরীক্ষাগুলির ভিতরে যদি আপনি নিশ্চিত করতে চান যে এটি বলা হয়েছিল। পরীক্ষা করে দেখুন https://facebook.github.io/jest/docs/en/mock-functions.html


হাই সি 4 কে! আপনি কি দয়া করে একটি উদাহরণ দিতে পারেন আপনি কীভাবে এটি পরীক্ষাগুলিতে ব্যবহার করবেন?
দিমো

আপনি কি বোঝাতে চেয়েছেন ? আপনাকে আপনার পরীক্ষাগুলিতে কোনও কিছু শুরু করতে হবে না, এটি আপনার কোডটিতে আপনি স্বয়ংক্রিয়ভাবে উপহাস করে localStorage। (যদি আপনি ব্যবহার করেন create-react-appএবং সমস্ত স্বয়ংক্রিয় স্ক্রিপ্টগুলি এটি প্রাকৃতিকভাবে সরবরাহ করে)
c4k

এরপরে আপনি পরীক্ষা করতে পারেন যে আপনার লোকালস্টোরেজমকের কাজগুলি আপনার পরীক্ষার মতো expect(localStorage.getItem).toBeCalledWith('token')বা এর expect(localStorage.getItem.mock.calls.length).toBe(1)ভিতরে যেমন কিছু করা হয়েছে তা নিশ্চিত করতে চাইলে এটি ব্যবহার করা হয়েছিল। পরীক্ষা করে দেখুন facebook.github.io/jest/docs/en/mock-functions.html
টম Mertz

10
এর জন্য আমি একটি ত্রুটি পাচ্ছি - jest.fn () মান অবশ্যই মক ফাংশন বা স্পাই হতে হবে। কোন ধারনা?
পল ফিৎসগেরাল্ড

3
আপনার যদি একাধিক পরীক্ষা ব্যবহার করে তবে এটি সমস্যার কারণ হবে না localStorage? "স্পিলওভার "টিকে অন্য পরীক্ষায় রোধ করতে আপনি কি প্রতিটি পরীক্ষার পরে গুপ্তচরদের পুনরায় সেট করতে চান না?
ব্র্যান্ডন স্টারজান

43

বর্তমানে (অক্টোবর '19) লোকাল স্টোরেজটি আপনি সাধারণত যেমন করতেন তেমন এবং রস-প্রতিক্রিয়া-অ্যাপ্লিকেশন ডক্সে বর্ণিত হিসাবে ঠাট্টা করে বা ঠাট্টা করা যায় না। এটি jsdom এ পরিবর্তনগুলির কারণে। আপনি এটি সম্পর্কে রসিকতা এবং জাসডম ইস্যু ট্র্যাকারগুলিতে পড়তে পারেন ।

কার্যকারণ হিসাবে, আপনি পরিবর্তে প্রোটোটাইপ গুপ্তচর করতে পারেন:

// does not work:
jest.spyOn(localStorage, "setItem");
localStorage.setItem = jest.fn();

// works:
jest.spyOn(window.localStorage.__proto__, 'setItem');
window.localStorage.__proto__.setItem = jest.fn();

// assertions as usual:
expect(localStorage.setItem).toHaveBeenCalled();

আসলে এটি আমার জন্য শুধু স্পাইঅন দিয়ে কাজ করে, সেট আইটেম ফাংশনটি ওভাররাইড করার দরকার নেইjest.spyOn(window.localStorage.__proto__, 'setItem');
যোহন দাহমণি

হ্যাঁ, আমি দুটিকে বিকল্প হিসাবে তালিকাভুক্ত করেছি, উভয় করার দরকার নেই।
বাস্তিয়ান স্টেইন

আমি সেটটি আইটেমটির ওভাররাইড ছাড়াই বোঝাতে চাইছিলাম
Y

আমি বুঝতে পারি না আমি বুঝতে পেরেছি। আপনি দয়া করে পরিষ্কার করতে পারেন?
বাস্তিয়ান স্টেইন

1
অই হ্যাঁ. আমি বলছিলাম আপনি প্রথম লাইন অথবা দ্বিতীয় লাইনটি ব্যবহার করতে পারেন। তারা বিকল্প যা একই জিনিস করে। আপনার ব্যক্তিগত পছন্দ যাই হোক না কেন :) বিভ্রান্তির জন্য দুঃখিত।
বাসটিয়ান স্টেইন

14

অথবা আপনি ঠিক এইভাবে একটি মক প্যাকেজ নিন:

https://www.npmjs.com/package/jest-localstorage-mock

এটি কেবলমাত্র স্টোরেজ কার্যকারিতা পরিচালনা করে না তবে এটি আপনাকে স্টোরকে ডাকা হয়েছিল কিনা তা পরীক্ষা করতে দেয়।


13

একটি ভাল বিকল্প যা undefinedমানগুলি পরিচালনা করে (এটিতে নেই toString()) এবং nullমান উপস্থিত না থাকলে ফিরে আসে । এটি reactv15 দিয়ে পরীক্ষা করেছেন , reduxএবংredux-auth-wrapper

class LocalStorageMock {
  constructor() {
    this.store = {}
  }

  clear() {
    this.store = {}
  }

  getItem(key) {
    return this.store[key] || null
  }

  setItem(key, value) {
    this.store[key] = value
  }

  removeItem(key) {
    delete this.store[key]
  }
}

global.localStorage = new LocalStorageMock

যুক্ত করার আইডিয়াটির জন্য অ্যালেক্সিস টাইলারকে ধন্যবাদ removeItem: ডেভেলপার.মোজিলা.আর.ইন.ইউএস
ডকস /

"নাল" এবং "অপরিজ্ঞাত" (আক্ষরিক স্ট্রিং)
মীনহুন 23

6

যদি আপনি কোনও উপহাসের জন্য এবং না খোদাইয়ের সন্ধান করেন তবে আমি যে সমাধানটি ব্যবহার করি তা এখানে:

export const localStorageMock = {
   getItem: jest.fn().mockImplementation(key => localStorageItems[key]),
   setItem: jest.fn().mockImplementation((key, value) => {
       localStorageItems[key] = value;
   }),
   clear: jest.fn().mockImplementation(() => {
       localStorageItems = {};
   }),
   removeItem: jest.fn().mockImplementation((key) => {
       localStorageItems[key] = undefined;
   }),
};

export let localStorageItems = {}; // eslint-disable-line import/no-mutable-exports

আমি সহজ আরম্ভের জন্য সঞ্চয়স্থান আইটেম রফতানি করি। IE আমি সহজেই এটি কোনও বস্তুতে সেট করতে পারি

জেস্ট + জেএসডমের নতুন সংস্করণগুলিতে এটি সেট করা সম্ভব নয় তবে লোকালস্টোরেজ ইতিমধ্যে উপলব্ধ এবং আপনি এটির জন্য এটি গুপ্তচর রাখতে পারেন:

const setItemSpy = jest.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem');

5

আমি গিথুব থেকে এই সমাধানটি পেয়েছি

var localStorageMock = (function() {
  var store = {};

  return {
    getItem: function(key) {
        return store[key] || null;
    },
    setItem: function(key, value) {
        store[key] = value.toString();
    },
    clear: function() {
        store = {};
    }
  }; 
})();

Object.defineProperty(window, 'localStorage', {
 value: localStorageMock
});

আপনি আপনার সেটআপ টেস্টে এই কোডটি sertোকাতে পারেন এবং এটি ঠিকঠাক কাজ করা উচিত।

আমি টাইপসিটিপ্ট সহ একটি প্রকল্পে এটি পরীক্ষা করেছি।


আমার জন্য অবজেক্ট.ডেফাইনপ্রোপার্টিটি কৌশলটি তৈরি করেছিল। ডাইরেক্ট অবজেক্ট অ্যাসাইনমেন্ট কাজ করে নি। ধন্যবাদ!
ভিসেন্স ফায়োস

4

দুর্ভাগ্যক্রমে, আমি যে সমাধানগুলি এখানে পেয়েছি সেগুলি আমার পক্ষে কার্যকর হয়নি।

তাই আমি জেস্ট গিটহব ইস্যুগুলির দিকে তাকিয়ে এই থ্রেডটি পেয়েছি

সর্বাধিক উত্সাহিত সমাধানগুলি হ'ল:

const spy = jest.spyOn(Storage.prototype, 'setItem');

// or

Storage.prototype.getItem = jest.fn(() => 'bla');

আমার পরীক্ষাগুলির কোনওরূপ windowবা Storageসংজ্ঞাও নেই। সম্ভবত এটি আমি ব্যবহার করছি জাস্টের পুরানো সংস্করণ।
এন্ট্রিক্সি

3

@ সি কে 4 হিসাবে প্রস্তাবিত ডকুমেন্টেশনের ঠাট্টায় ব্যবহারের জন্য স্পষ্ট ব্যাখ্যা রয়েছে localStorage। তবে মক ফাংশনগুলি কোনও localStorageপদ্ধতি প্রয়োগ করতে ব্যর্থ হয়েছিল ।

নীচে আমার প্রতিক্রিয়া উপাদানটির বিস্তারিত উদাহরণ যা ডেটা লেখার এবং পড়ার জন্য বিমূর্ত পদ্ধতি ব্যবহার করে,

//file: storage.js
const key = 'ABC';
export function readFromStore (){
    return JSON.parse(localStorage.getItem(key));
}
export function saveToStore (value) {
    localStorage.setItem(key, JSON.stringify(value));
}

export default { readFromStore, saveToStore };

ত্রুটি:

TypeError: _setupLocalStorage2.default.setItem is not a function

স্থির করুন:
উপহাসের জন্য মক ফাংশন নীচে যুক্ত করুন (পথ .jest/mocks/setUpStore.js:)

let mockStorage = {};

module.exports = window.localStorage = {
  setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
  getItem: (key) => mockStorage[key],
  clear: () => mockStorage = {}
};

স্নিপেট এখানে থেকে রেফারেন্স করা হয়


2

টাইপসক্রিপ্ট সহ একটি প্রকল্পের জন্য এটি সমাধান করতে এখানে কিছু অন্যান্য উত্তর রিফিড বন্ধ করুন। আমি এটির মতো লোকালস্টোরেশনমক তৈরি করেছি:

export class LocalStorageMock {

    private store = {}

    clear() {
        this.store = {}
    }

    getItem(key: string) {
        return this.store[key] || null
    }

    setItem(key: string, value: string) {
        this.store[key] = value
    }

    removeItem(key: string) {
        delete this.store[key]
    }
}

তারপরে আমি একটি লোকালস্টোরেজ র্যাপার ক্লাস তৈরি করেছি যা আমি সরাসরি বিশ্বব্যাপী স্থানীয় স্টোরেজ ভেরিয়েবল অ্যাক্সেস না করে অ্যাপ্লিকেশনটিতে স্থানীয় স্টোরেজে সমস্ত অ্যাক্সেসের জন্য ব্যবহার করি। পরীক্ষার জন্য মোড়কে মক সেট করা সহজ করে তোলে।


2
    describe('getToken', () => {
    const Auth = new AuthService();
    const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Ik1yIEpvc2VwaCIsImlkIjoiNWQwYjk1Mzg2NTVhOTQ0ZjA0NjE5ZTA5IiwiZW1haWwiOiJ0cmV2X2pvc0Bob3RtYWlsLmNvbSIsInByb2ZpbGVVc2VybmFtZSI6Ii9tcmpvc2VwaCIsInByb2ZpbGVJbWFnZSI6Ii9Eb3Nlbi10LUdpci1sb29rLWN1dGUtbnVrZWNhdDMxNnMtMzExNzAwNDYtMTI4MC04MDAuanBnIiwiaWF0IjoxNTYyMzE4NDA0LCJleHAiOjE1OTM4NzYwMDR9.YwU15SqHMh1nO51eSa0YsOK-YLlaCx6ijceOKhZfQZc';
    beforeEach(() => {
        global.localStorage = jest.fn().mockImplementation(() => {
            return {
                getItem: jest.fn().mockReturnValue(token)
            }
        });
    });
    it('should get the token from localStorage', () => {

        const result  = Auth.getToken();
        expect(result).toEqual(token);

    });
});

একটি মক তৈরি করুন এবং এটি globalঅবজেক্টে যুক্ত করুন


2

বিদ্রূপ এড়াতে আপনি এই পদ্ধতির ব্যবহার করতে পারেন।

Storage.prototype.getItem = jest.fn(() => expectedPayload);

2

এই স্নিপেটগুলি দিয়ে আপনার স্থানীয় স্টোরেজকে উপহাস করতে হবে

// লোকালস্টোরেজ.জেএস

var localStorageMock = (function() {
    var store = {};

    return {
        getItem: function(key) {
            return store[key] || null;
        },
        setItem: function(key, value) {
            store[key] = value.toString();
        },
        clear: function() {
            store = {};
        }
    };

})();

Object.defineProperty(window, 'localStorage', {
     value: localStorageMock
});

এবং ঠাট্টা কনফিগারেশনে:

"setupFiles":["localStorage.js"]

কিছু জিজ্ঞাসা করুন নির্দ্বিধায়।


1

নিম্নলিখিত সমাধানটি কঠোর প্রকারের স্ক্রিপ্ট, ESLint, TSLint, এবং প্রিটিয়ার কনফিগারেশনের সাথে পরীক্ষার জন্য উপযুক্ত { "proseWrap": "always", "semi": false, "singleQuote": true, "trailingComma": "es5" }:

class LocalStorageMock {
  public store: {
    [key: string]: string
  }
  constructor() {
    this.store = {}
  }

  public clear() {
    this.store = {}
  }

  public getItem(key: string) {
    return this.store[key] || undefined
  }

  public setItem(key: string, value: string) {
    this.store[key] = value.toString()
  }

  public removeItem(key: string) {
    delete this.store[key]
  }
}
/* tslint:disable-next-line:no-any */
;(global as any).localStorage = new LocalStorageMock()

কীভাবে গ্লোবাল.লোকালস্টোরেজ আপডেট করবেন তার জন্য HT / https://stackoverflow.com/a/51583401/101290


1

টাইপস্ক্রিপ্টে একই কাজ করতে, নিম্নলিখিতগুলি করুন:

নিম্নলিখিত বিষয়বস্তু সহ একটি ফাইল সেটআপ করুন:

let localStorageMock = (function() {
  let store = new Map()
  return {

    getItem(key: string):string {
      return store.get(key);
    },

    setItem: function(key: string, value: string) {
      store.set(key, value);
    },

    clear: function() {
      store = new Map();
    },

    removeItem: function(key: string) {
        store.delete(key)
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

তারপরে আপনি আপনার জেস্ট কনফিগারেশনের অধীনে আপনার প্যাকেজ.জসনে নিম্নলিখিত লাইনটি যুক্ত করুন

"setupTestFrameworkScriptFile":"PATH_TO_YOUR_FILE",

অথবা আপনি যেখানে স্থানীয় স্টোরেজকে উপহাস করতে চান সেই পরীক্ষার ক্ষেত্রে আপনি এই ফাইলটি আমদানি করুন।


0

এটি আমার পক্ষে কাজ করেছে,

delete global.localStorage;
global.localStorage = {
getItem: () => 
 }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.