Mở đầu

Ở phần trước tôi đã giới thiệu cơ bản về cách cài đặt cũng như cách kiểm tra xem code của mình có đúng như kết quả mong đợi. Phần này tôi sẽ giới thiệu các kỹ thuật liên quan đến Integration test. Cùng bắt đầu thôi!

1.Testing asynchronous code

Bất đồng bộ trong Javascript có 2 loại cơ bản là: Callbacks Promises. Chúng ta sẽ lần lượt tìm hiểu cách viết test với các loại này như thế nào.

Callbacks

Cùng xem ví dụ sau để hiểu rõ hơn

//uppercase.js
function uppercase(str, callback) {
  callback(str.toUpperCase())
}
module.exports = uppercase

//uppercase.test.js
const uppercase = require('./src/uppercase')

test(`uppercase 'test' to equal 'TEST'`, (done) => {
  uppercase('test', (str) => {
    expect(str).toBe('TEST')
    done()
  }
})

Ở file uppercase.js viết hàm thực hiện đổi str truyền vào sang chữ viết hoa. Để có thể kiểm tra xem tham số test truyền vào đã được viết hoa hay chưa, ta phải đợi call back được gọi, bằng cách gọi đến hàm done()

Promises

Với functions mà trả về một promises, đầu tiên chúng ta return về promises rồi mới tiến hành so sánh. Ví dụ:

//uppercase.js
const uppercase = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject('Empty string')
      return
    }
    resolve(str.toUpperCase())
  })
}
module.exports = uppercase

//uppercase.test.js
const uppercase = require('./uppercase')
test(`uppercase 'test' to equal 'TEST'`, () => {
  return uppercase('test').then(str => {
    expect(str).toBe('TEST')
  })
})

// Trường hợp promises bị reject
test(`uppercase 'test' to equal 'TEST'`, () => {
  return uppercase('').catch(e => {
    expect(e).toMatch('Empty string')
  })
})

Async/await

Test function mà return về promises, chúng ta cũng có thể sử dụng async/await. Với cách này trông code sẽ đơn giản, và ngắn gọn hơn.

//uppercase.test.js
const uppercase = require('./uppercase')
test(`uppercase 'test' to equal 'TEST'`, async () => {
  const str = await uppercase('test')
  expect(str).toBe('TEST')
})

2.Mocking

Trong khi test, mocking cho phép bạn test các function liên quan đến:

  • Database
  • Network requests
  • Truy cập đến các File

Sử dụng mock, bạn có thể kiểm tra xem module function đã được gọi chưa và tham số nào được sử dụng với:

  • expect().toHaveBeenCalled(): kiểm tra xem spied function đã được gọi chưa
  • expect().toHaveBeenCalledTimes(): đém số lần spied function được gọi.
  • expect().toHaveBeenCalledWith(): kiểm tra function được gọi với tập các parameter chỉ định.
  • expect().toHaveBeenLastCalledWith(): kiểm tra các tham số truyền vào lần cuối đã được gọi chưa.

Mock an entire package

Jest cung cấp một cách dễ dàng để mock entire package. Tạo folder __mocks__ trong project root, trong folder này tạo file js cho mỗi package mà bạn muốn sử dụng. Ví dụ mock log function của package ta làm như sau: Tạo file __mocks__/mathjs.js và thêm đoạn code sau:

module.exports = {
  log: jest.fn(() => 'test')
}

Thêm các function mà bạn muốn mock như sau:

const mathjs = require('mathjs')

test(`The mathjs log function`, () => {
  const result = mathjs.log(10000, 10)
  expect(result).toBe('test')
  expect(mathjs.log).toHaveBeenCalled()
  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)
})

Mock a single function

Sử dụng `jest.fn()` để mock một function

const mathjs = require('mathjs')

mathjs.log = jest.fn(() => 'test')
test(`The mathjs log function`, () => {
  const result = mathjs.log(10000, 10)
  expect(result).toBe('test')
  expect(mathjs.log).toHaveBeenCalled()
  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)
})

Tham khảo

https://jestjs.io/docs/en/getting-started

https://callstack.com/blog/testing-react-native-with-the-new-jest-part-1-snapshots-come-into-play/#.12zbnbgwc