มาเขียน Test React ด้วย Enzyme กันเถอะ (ฉบับกระชับ)

TAeng Trirong Pholphimai
Nellika
Published in
3 min readOct 17, 2019

--

เกริ่น…

ใช้อะไรบ้าง

- jest
- enzyme
- chai
- sinon
- babel

ทำอะไรบ้าง

1. Initial Project
2. Install package
3. Config
4. เริ่มเขียน Test

1. Initial Project

ใช้ create-react-app my-app ในการ Build Project

https://github.com/facebook/create-react-app

npx create-react-app my-app // build react app
cd my-app // เข้าไดเรกตอรี่
npm start // ทดสอบ run project

2. Install package

ก่อนที่จะเขียน Test ต้องลง package ก่อน ตามนี้

npm install --save-dev jestnpm install --save-dev enzyme enzyme-adapter-react-16npm install --save-dev chainpm install --save-dev sinonnpm install --save-dev @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties

อธิบาย package

jest เป็นตัวรัน test
enzyme เป็นตัว Render Components โดยที่เราไม่ต้องเปิด Browser ขึ้นมา
chai เป็นตัวเปรียบเทียบค่าที่คาดหวัง เขียน test ก็ต้องมีการคาดหวังสิ่งที่เกิด
babel เป็นตัวแปลงโค้ด JavaScript เวอร์ชั่นใหม่ ให้เป็นเวอร์ชั่นที่ Browser สามารถรันได้

3. Config

สร้าง src/setupTest.js

import { configure } from 'enzyme'import Adapter from 'enzyme-adapter-react-16'configure({ adapter: new Adapter() })

สร้าง babel.config.js

module.exports = {presets: ['@babel/preset-env', '@babel/preset-react'],plugins: ['@babel/plugin-proposal-class-properties']}

สร้าง jest.config.js

module.exports = {rootDir: '.',displayName: { name: 'enzyme-setup', color: 'blue' },verbose: true,errorOnDeprecated: true,roots: ['./Tests'],setupFilesAfterEnv:["<rootDir>src/setupTest.js"]}

4. เริ่มเขียน Test

เพิ่ม โค้ดใน package.json

"scripts": {
...
“test”: “jest”...
}

สร้าง Tests/App.test.js

อธิบายโค้ด

describe เป็นส่วนที่จะบอกว่า เรากำลัง Test Component ไหนอยู่
describe(‘<MyComponent />’, () => {…})

it เป็นส่วนที่จะบอกว่า เรากำลัง Test Case ไหนอยู่
it(‘renders three <Foo /> components’, () => {…})

shallow เป็นการเรนเดอร์แบบตื้น ไม่ได้ render ทั้ง component ทำให้ทำงานเร็วกว่า mount
const wrapper = shallow(<MyComponent />)

mount เป็นการเรนเดอร์แบบเต็ม render ทั้ง component ทำให้ทำงานช้ากว่า shallow
const wrapper = mount(<Foo onButtonClick={onButtonClick} />)

render เป็นการเรนเดอร์เป็น static html
const wrapper = render(<div className=”myClass” />)

expect เป็นการคาดหวังค่า
ยกตัวอย่างโค้ดด้านล่าง เป็นการคาดหวังว่า จะมี <Foo></Foo> 3 อัน ใน <MyComponent />
const wrapper = shallow(<MyComponent />)
expect(wrapper.find(Foo)).to.have.lengthOf(3)

รันคำสั่ง npm test

อุ๋ย~!! เฟลอะแกร
ถึงตอนนี้ตั้งสติก่อนครับ อ่าน error ก่อน แล้วดูว่ามันบอกอะไรเรา
ถูกต้องครับ เรายังไม่มี MyComponent

สร้าง src/components/MyComponent.js

npm test
ยังเฟล อยู่ใช่ไหม

สร้าง src/components/Foo.js

มาถึงตอนนี้ Structure Project จะประมาณนี้

npm test

อีหยังวะ เฟล อีกแย้ววว ใจเย็นๆครับ อ่าน error ก่อน

อธิบายโค้ด

case 1
const wrapper = shallow(<MyComponent />)
กำหนด shallow <MyComponent />
expect(wrapper.find(Foo)).to.have.lengthOf(3)
คาดหวังว่า เราคาดหวังว่า <Foo></Foo> จะ 3 อัน <MyComponent/>

อ่าน Error

case 1 สังเกตตรง Expected value 3 คือค่าที่เราคาดหวัง
แต่ตรง Received มันนับได้ 0 ก็หมายความว่าตอนนี้มันยังไม่มี <Foo></Foo>

ทำไงดีน๊าา
งั้นก็ไปเพิ่ม <Foo></Foo> สัก 3 อัน ใน Component MyComponent สิ
src/components/MyComponent.js

npm test

เย้ ผ่านละจร้า Case 1

อธิบายโค้ด

Case2
const onButtonClick = sinon.spy()
กำหนด Event ให้กับ onButtonClick
const wrapper = mount(<Foo onButtonClick={onButtonClick} />)
กำหนด mount ส่ง Event onButtonClick ผ่าน props ของ component Foo
wrapper.find(‘button’).simulate(‘click’)
หาแท็ก button แล้วคลิก 1 ครั้ง

อ่าน Error

case 2 สังเกตที่ Component Foo เรายังไม่มีแท็ก button ทำให้โค้ดส่วนนี้
wrapper.find(‘button’).simulate(‘click’) ทำงานไม่ได้

ทำไงดีน๊าา

ก็เพิ่ม <button onClick={onButtonClick}></button> ใน Component Foo สิ
src/components/Foo.js

npm test

เย้ ผ่านละจร้า Case 2 พอถึงตอนนี้ ตบมือให้ตัวเองหน่อยครับ เก่งมากๆ ที่ทนอ่านมาถึงตรงนี้

อธิบายโค้ด

Case3
const wrapper = render(<Foo/>)
กำหนด render <Foo/>
expect(wrapper.text()).to.contain(‘unique’)
คาดหวังว่าจะมีคำว่า unique ใน Component Foo

อ่าน Error

case 3 สังเกตตรง Expected Value เป็น undefined เพราะหาคำว่า unique ไม่เจอ
ส่วนตรง Received มีแต่คำว่า Foo

ทำไงดีน๊าา

ก็เพิ่มคำว่า unique เข้าไปใน Component Foo สิ
src/components/Foo.js

npm test

เย้ ผ่านหมดแล้ว

ศึกษา function อื่นๆ ของ Enzyme ได้ที่ https://airbnb.io/enzyme/

สรุป

หากผิดพลาดประการใด ขออภัยด้วยครับ หวังว่าจะเป็นประโยชน์สำหรับเพื่อนๆที่กำลังศึกษานะครับ ถ้ามีเวลาจะมา Edit ให้ข้อมูลแน่นกว่านี้ และ เป็นประโยชน์มากกว่านี้

--

--