---
# System prepended metadata

title: User Event - 模擬使用者操作

---

# User Event - 模擬使用者操作


- [為什麼要使用 user event 呢？](https://hackmd.io/s1KmikUFQviFYIoHdWexBA#%E7%82%BA%E4%BB%80%E9%BA%BC%E8%A6%81%E4%BD%BF%E7%94%A8-user-event-%E5%91%A2%EF%BC%9F)
- [常用的操作行為](https://hackmd.io/s1KmikUFQviFYIoHdWexBA#%E5%B8%B8%E7%94%A8%E7%9A%84%E6%93%8D%E4%BD%9C%E8%A1%8C%E7%82%BA)

--- 
#### 為什麼要使用 user event 呢？

fireEvent 雖然一樣能調用事件，但 use event 可以更容易模擬使用者與瀏覽器的交互行為，官方文件上有舉例：
```!
For example, when a user types into a text box, the element has to be focused, and then keyboard and input events are fired and the selection and value on the element are manipulated as they type.
```
用戶輸入文字框時會有一連串的交互行為，包含一開始文字框的 focus 後續會觸發鍵盤的輸入事件再輸入內容時也同時在操作元素的值。

---

**User Event 可以更容易模擬使用者與瀏覽器的交互行為**
<aside>
👉 使用 creat-react-app 建立專案的情況下，已經幫我們安裝好 user event 了，而安裝好的版本是 v13 ，目前 user event 已更新至 v14 版本，但文章還是會先按照 v13 版本進行解釋。
</aside>
    
--

如果專案還沒有安裝 user event ，可以透過底下指令安裝：

```node!
npm install --save-dev @testing-library/user-event @testing-library/dom
```

接下來來認識 user event 好用的幾種操作行為吧！

---
    
#### 常用的操作行為
- User Event 的好用操作行為：
    - `Click`, `dblClick`
        
        ```jsx!
        // 記得引入 userEvent 
        import userEvent from '@testing-library/user-event'
        ```
        
        ```jsx!
        test('click', () => {
          render(
            <div>
              <label htmlFor="checkbox">Check</label>
              <input id="checkbox" type="checkbox" />
            </div>,
          )
        
          userEvent.click(screen.getByText('Check'))
          expect(screen.getByLabelText('Check')).toBeChecked()
        })
        ```
        除此之外跟 click 相關的還有 dblClick 可以透過此方式判斷點擊 checkbox 兩次後是否不是打勾狀態：

        ```javascript!
        test('click', () => {
          render(
            <div>
              <label htmlFor="checkbox">Check</label>
              <input id="checkbox" type="checkbox" />
            </div>,
          )

          userEvent.dblClick(screen.getByText('Check'))
          expect(screen.getByLabelText('Check')).not.toBeChecked()
        })
        ```

        
    - `type`
        - `type(element, text, [options])` 該方法可以使用在 **input** 或 **textarea**，透過 React Testing Library 選取該 input 或 textarea 後可以輸入要顯示的數字，會**模擬使用者操作時點擊 input 的行為後再去做輸入**。
        - 假設今天有一個元件 Input 如下：
        
            ```javascript
                import { useState } from "react";

                const Input = () => {
                  const [value, setValue] = useState('');
                  const changeValue = (value) => setValue(value);

                  return (
                    <>
                      <input
                        value={value}
                        onChange={(e) => changeValue(e.target.value)}
                      />
                      <h1>{value}</h1>
                    </>
                  );
                };

                export default Input;

            ```

            可透過 type 去模擬使用者輸入進行測試：
            
            ```javascript
            import React from "react";
            import { render, screen } from "@testing-library/react";
            import userEvent from "@testing-library/user-event";
            import Input from "./TestInput";

            test("type", () => {
              render(<Input />);
              userEvent.type(screen.getByRole("textbox"), 'Hello');
              expect(screen.getByText('Hello')).toBeInTheDocument();
            });
            ```
            且除了輸入文字內容外，也可以輸入一些特殊符號，如下圖(圖片取自官方文件)：
            
            ![特殊符號](https://i.imgur.com/zF75iIW.png)
            
            使用方式只要像這樣直接加進去：
            
            ```javascript
                test("type", () => {
                  render(<Input />);
                  userEvent.type(screen.getByRole("textbox"), 'Helli{backspace}o');
                  expect(screen.getByText('Hello')).toBeInTheDocument();
                });
            ```
            
其他還有很多方法像是：

- `keyboard` ：輸入的鍵盤事件，與 type 相似但**並沒有單擊行為**
- `upload`：用於**檔案上傳**的測試
- `selectOptions` ：選擇 **selet** 的選項
    
都可以參閱[官方文件](https://testing-library.com/docs/user-event/intro/)唷！
    

---
參考文章

https://testing-library.com/docs/ecosystem-user-event
https://testing-library.com/docs/user-event/intro/