Unit testing các component Vue.js bằng các tool Vue testing và Jest (P2): Test Vue.js Components deep render trong Jest

Hãy cùng xem cách tham khảo cách sử dụng các vue-test-utils để test một cây component đã được render.

Trong Phần 1 chúng ta đã hiểu được cách sử dụng Shadow Rendering để test một component riêng biệt và tránh việc các component bị sub-free từ việc render.

Nhưng trong một số trường hợp, chúng ta lại muốn test một component đại diện cho cả 1 group, hoặc các phần tử như trong Atomic Design.

Bổ sung một Message Component

Đối với hai component Message và MessageList, bên cạnh việc viết các unit test cho chúng, thì chúng ta còn có thể test cả hai cái như một unit nữa.

Đầu tiên chúng ta tạo components/Message.vue:

<template>
    <li class="message">{{message}}</li>
</template>

<script>
  export default {
    props: ['message']
  }
</script>

Và update components/MessageList.vue để sử dụng nó:

<template>
    <ul>
        <Message :message="message" v-for="message in messages"/>
    </ul>
</template>

<script>
import Message from './Message'

export default {
  props: ['messages'],
  components: {
    Message
  }
}
</script>

Test MessageList bằng Message Component

Để test MessageList bằng Deep Rendering, chúng ta chỉ cần sử dụng mount chứ không cầnshallow trong test/MessageList.test.js đã tạo trước:

import { mount } from 'vue-test-utils'
import MessageList from '../src/components/MessageList'

describe('MessageList.test.js', () => {
  let cmp

  beforeEach(() => {
    cmp = mount(MessageList, {
      // Beaware that props is overriden using `propsData`
      propsData: {
        messages: ['Cat']
      }
    })
  })

  it('has received ["Cat"] as the message property', () => {
    expect(cmp.vm.messages).toEqual(['Cat'])
  })

  it('has the expected html structure', () => {
    expect(cmp.element).toMatchSnapshot()
  })
})

Không liên quan nhưng mà, bạn đã bao giờ nghĩ về beforeEach? Đây là một phương pháp “sạch” để tạo một component “sạch” trước mỗi test, một điều rất quan trọng trong unit testing, vì các test không nên phụ thuộc lẫn nhau,

Cả mount và shallow đều sử dụng API hệt như nhau, khác nhau nằm ở chỗ render. Tôi sẽ từ từ show cho bạn API này trong suốt cả series.

Nếu bạn cho chạy npm t bạn sẽ thấy ngay test thất bại vì Snapshot không khớp với MessageList.test.js. Để thực hiện lại, hãy chạy cùng với option -u:

npm t -- -u

Sau đó nếu mở và kiểm tra test/__snapshots__/MessageList.test.js.snap, bạn sẽ thấy có class="message", đồng nghĩa rằng component đã được render.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MessageList.test.js has the expected html structure 1`] = `
<ul>
  <li
    class="message"
  >
    Cat
  </li>
</ul>
`;

Luôn nhớ rằng phải tránh deep render khi có dấu hiệu sẽ xuất hiện các effect phụ, vì một khi các children component xuất hiện thì createdmount sẽ bị kích hoạt, và có thể sẽ kèm theo các HTTP call hoặc các hiệu ứng khác mà chả ai muốn đụng tới. Nếu bạn muốn thử, thêm component Message.vue vào console.log trong hook đã tạo:

export default {
  props: ['message'],
  created() {
    console.log('CREATED!')
  }
}

Sau đó nếu chạy lại các test bằng npm t, bạn sẽ thấy dòng text "CREATED!" trong output cuối cùng. Vì vậy hãy cẩn thận.

Phần 3: Test các Style and cấu trúc của các Vue.js Components trong Jest

TopDev via alexjoverm.github.io