簡體   English   中英

如何使用 useState 鈎子設置初始狀態

[英]How to set an initial state using the useState hook

我使用 useState 鈎子編寫了一個功能組件,該組件本身工作正常,但我無法對其進行測試。 我不明白如何在我的組件中創建初始狀態。 我嘗試了多種模擬 useState 的方法,但都沒有奏效:

describe('<Component/>', () => {
    beforeEach() = > {
        jest.spyOn(Readt, 'useState').mockImplementation( () => React.useState(['test']));
        //Also tried this:
        //React['useState'] = jest.fn().mockImplementation( () => React.useState(['test']));
    }
    it('should match snapshot', () => {
        expect(wrapper).toMatchSnapshot()
    }
}

我也看過這篇文章,但無法讓它為我工作

如何在笑話和酶中為 useState Hook 設置初始狀態?

我還讀到你不應該在單元測試中模擬 useState 但是如果你不模擬它,你如何為你的組件設置初始狀態?

謝謝。

編輯:關於下面的答案:

傳入 prop 不會改變我要測試的狀態。

我有一個按鈕,當點擊(一種狀態)時呈現一個輸入框,當用戶輸入(另一種狀態)並按下 OK 按鈕(另一種狀態)時,它會根據輸入框中的內容創建一個按鈕。

傳遞的道具有助於呈現按鈕列表,但它無法控制用戶在輸入框中鍵入的內容。 我試圖在輸入框中設置一個狀態,然后模擬點擊 OK 按鈕並測試它。 我不是要測試本機 useState 功能的反應。 我只是想使用已經有“wrapper.setState”的酶,但我如何使用 useState 做到這一點?

理想情況下,我想設置我的組件,設置用戶在輸入框中鍵入內容的狀態,然后測試確定按鈕是否執行了它應該執行的操作。 無需模擬之前的所有點擊。

組件的狀態在其內部,這是理解 React 組件的重要部分。 一旦你“理解”了它,你就可以理解任何測試都不應該試圖改變它。

那么你如何為你的組件設置一個初始狀態呢?

您將一個值傳遞給組件內部的useState鈎子。 然后,您的測試應該使用該初始狀態測試您的組件……他們應該只傳入props來更改它,就像您的非測試代碼一樣。

事實上,即使你能以某種方式改變你的初始狀態(這是不可能的 AFAIK),你的測試代碼也不應該做任何非測試代碼所做的事情(除了設置模擬真實環境的測試環境),因為整個過程測試是為了驗證您的非測試代碼是否有效。

同樣,您永遠不想測試您正在測試的任何東西的內部結構,無論是 React 組件還是其他任何東西。

如果你這樣做,你編寫的每個測試都會在這些內部發生任何變化的那一刻中斷,而測試的一個重要價值在於它們讓你更容易重構(如果測試內部)。 相反,您希望使用您的測試工具來衡量您的組件的輸出(即它生成的 HTML)。

再說一次,這甚至與 React 無關。 任何東西的良好軟件測試不會試圖弄亂那個東西的內部結構,無論是改變還是衡量它們。 取而代之的是,好的測試側重於externals ,因為同樣是所有非測試代碼都可以使用,並且因為從概念上講,您測試的所有內容都應該是測試代碼的“黑匣子”。

編輯:回復評論/問題編輯

老實說,您的編輯並沒有真正改變我的答案,只是它提醒我 Enzyme 確實有一種方法可以改變測試中的狀態(我自己從來沒有使用過,我忘記了它的存在)。

但同樣,僅僅因為某些事情是可能的並不意味着它是一個好主意,並且再次強調,您想測試您測試的任何東西外觀(不僅僅是 React 組件)。 React 組件的狀態就像函數內部的變量:它是該函數/組件的內部變量,您應該避免直接測試。

您想要測試的是外部部件,並且(根據您的編輯)它似乎不是props ……但它仍然是外部的東西:DOM。

所以我建議做的是(再次)非測試代碼正在做的事情:“點擊”你的按鈕。 Enzyme 通過其“模擬”方法 ( https://airbnb.io/enzyme/docs/api/ReactWrapper/simulate.html ) 使這變得非常容易。

如果您只是模擬創建您想要的狀態的按鈕序列,您將只測試外部(即測試您的代碼將在生產中使用的相同方式),但您將能夠測試您想要的任何情況。

如何根據環境設置一個值? Jest 將環境變量NODE_ENV為“test”:

const inTest = process.env.NODE_ENV === 'test'

[value, setValue] = useState(inTest ? mockValue : defaultValue)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM