Migrate jasmine ไปใช้ jest ใน Angular 6

อะกิมาบอกว่า jest น่าสนใจดีนะ จำได้ว่ามีคนเคยชวนไปใช้ jest แต่ตอนนั้นก็ยังไม่ได้สนใจอะไร ตอนนี้พอมีเวลาก็เลยมาลองซะหน่อย มี project ทดสอบอยู่ตัวนึงที่เอาไว้ใช้สอน robot คือ ng-calculator ซึ่งเดิมใช้ jasmine อยู่ เดี๋ยวจะมาลองเปลี่ยนเป็น jest ดู

ไปอ่านเจอจากใน xfive เจอว่ามันต้องแก้ไขเล็กน้อยเพื่อให้มันใช้ด้วยกันได้ เพราะตัว framework มันมี syntax ไม่เหมือนกัน ไปเจอมาอีกว่า มันมีตัว jest-codemod ที่ช่วย convert จาก code เดิมที่ใช้ jasmine ไปเป็น code ที่ใช้ jest แต่!!!! มันใช้ได้กับ javascript เท่านั้น ใช้กับ typescript ไม่ได้ ดังนั้นช่างแม่งก่อน ลองทำไปแบบลูกทุ่งละกัน

เริ่มจาก ลงของที่ต้องมีก่อน

yarn add --dev jest jest-preset-angular @types/jest

ของที่มันลง ประกอบด้วย

  • jest – คือ ตัว test platform ของ jest
  • jest-preset-angular – คือ configuration ที่ตั้งค่ามาให้แล้ว
  • @types/jest – คือ typing สำหรับ jest

เสร็จแล้วไปเพิ่มไอ้นี่ลงใน package.json

"jest": {
  "preset": "jest-preset-angular",
  "setupTestFrameworkScriptFile": "<rootDir>/src/setupJest.ts"
}

ถัดมา สร้างไฟล์ setupJest.ts วางไว้ใน /src มีข้างในเป็นแบบนี้

import 'jest-preset-angular';

ที่เหลือไปแก้ npm script ในไฟล์ package.json

"test": "jest",
"test:watch": "jest --watch",

หลังจากนั้นก็ลองสั่ง npm run test ก็จะเห็นได้ว่ามันใช้ jest แล้ว แต่ error บานเลย เพราะว่า code ที่เรามีอยู่ใน test มันยังใช้กับ jest ไม่ได้

สิ่งที่จะต้องแก้หลังจากย้ายมาใช้ Jest

jasmine.createSpyObj

จากเดิมตอนที่เราสร้าง mock ด้วย jasmine.createSpyObj('name', ['key']) ก็ให้เปลี่ยนเป็น {key: jest.fn()} แทน เช่น

const mockObject = jasmine.createSpyObj('mockObject', ['doSomething'];

เปลี่ยนเป็น

const mockObject = {doSomething: jest.fn()};

เอา @types/jasmine module ออกจาก package.json

yarn remove @types/jasmine

jasmine.createSpy(‘name’)

ตรงที่ใช้ jasmine.createSpy ก็ให้เปลี่ยนมาใช้ jest.fn() แทน

and.returnValue()

ตรงที่ stub value ไว้ด้วย and.returnValue() ก็ใช้ mockReturnValue() เช่น

const mockObject = jasmine.createSpyObj('mockObject', ['doSomething']);
mockObject.doSomething.and.returnValue(1);

ก็จะกลายเป็น

const mockObject = {doSomething: jest.fn()};
mockObject.doSomething.mockReturnValue(1);

spyOn().and.callFake()

ตรงที่ใช้ spyOn().and.callFake(() => {}) ก็ใช้ jest.spyOn().mockImplementation(() => {}) แทน

asymmetric matcher เช่น jasmine.any หรือ jasmine.objectContaining

ก็เปลี่ยนไปใช้ expect.any, expectObjectContaining แทน

อยากดู code coverage

ในตัว jest มี code coverage option มาให้ด้วย คือ --coverage ดังนั้นเราก็แค่เพิ่มเข้าไปใน npm script

"test:coverage": "jest --coverage",

พอสั่ง npm run test:coverage มันก็จะแสดง code coverage ออกมาให้ดูด้วยสวยงามเลย

จบ ลองเข้าไปดูของที่ลอง migrate มาแล้วได้ที่ https://github.com/chonla/ng-calculator ใน branch jest

อ้างอิง

  • https://www.xfive.co/blog/testing-angular-faster-jest/
  • https://facebook.github.io/jest/docs/en/getting-started.html

One thought on “Migrate jasmine ไปใช้ jest ใน Angular 6

Leave a Reply

Your email address will not be published. Required fields are marked *