Jest 如何 mock localStorage

在撰寫測試經常會需要 mock window class 的操作,例如預期呼叫 alert 啦,呼叫 localstorage 等,那麼為何只是說要呼叫呢?
因為很多時候要測試的是有沒有預期的執行,而不是執行過後的結果是什麼,例如 alert 期望他被呼叫到,而結果是啥並不重要,這算是寫測試到現在的一些心得吧XD

那麼這次在 mock window 內的 localStorage 卡了一下,後來終於找到了方法讓測試 mock 成功。

範例

那麼這次要測試的情境是,我寫了一個 class 他會去呼叫 localStorageremoveItemclear 這兩個函式,他們只要被呼叫就好了,至於結果如何,瀏覽器早就幫我們測試好了。

describe('mock localStorage', () => {
  beforeEach(() => {
    const localStorageMock = {
      removeItem: jest.fn(),
      clear: jest.fn()
    }

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

  afterEach(() => {
    jest.clearAllMocks()
  })
  
  it('should call localStorage clear', () => {
    // ...
    
    expect(localStorage.clear).toHaveBeenCalled()
  })
})

這邊使用了 Object.defineProperty 去複寫 window 內的 localStorage 變成我們自己 mock 的物件,變且已經寫好了 jest.fn() 所以當 localStorageMock.clear 被呼叫就會如我們測試的預期了。