Ejekan tidak menggigit! Menguasai Mocking dengan Perpustakaan Pengujian React

Terjemahan artikel disiapkan untuk mengantisipasi dimulainya kursus "Tes Otomasi dalam JavaScript" .










Mengolok - jangan menggigit!



Mereka dirancang untuk membantu Anda membuat pengujian yang lebih sederhana dan lebih andal. Dalam rangkaian artikel ini, saya akan menunjukkan kepada Anda pola yang saya andalkan saat mengejek (atau "mematikan") komponen React.



Berikut adalah contoh yang bagus dari rintisan komponen. Saya menggunakan jest.mock, yang akan kita lihat lebih detail di bawah.



jest.mock("../src/PostContent", () => ({
  PostContent: jest.fn(() => (
    <div data-testid="PostContent" />
  ))
}))




Stub komponen React biasanya tidak terlihat lebih rumit. Perhatikan nilai stub yang sangat sederhana ( div) dan atribut data-testidyang sangat memudahkan kita untuk menemukan instance yang dirender di DOM. Sesuai ketentuan, pengenal pengujian yang digunakan harus cocok dengan nama komponen. Dalam hal ini, memang demikian PostContent.



Sebelum kita melihat bagaimana mereka digunakan, pertama-tama mari kita ingat apa itu tiruan dan mengapa Anda mungkin ingin menggunakannya.



Apa itu tiruan?



Di dunia JavaScript, istilah tiruan sangat banyak digunakan untuk merujuk pada implementasi tiruan atau pengujian ganda . Penerapan palsu hanyalah nilai yang menggantikan yang lain dalam kode produksi Anda saat pengujian Anda berjalan. Mereka mencoba antarmuka objek yang diganti, sehingga kode Anda lainnya berfungsi seolah-olah tidak ada penggantinya.



Ada beberapa alasan berbeda mengapa Anda mungkin ingin melakukan ini; kita akan melihatnya dengan contoh.



Jika Anda tertarik untuk mempelajari lebih lanjut tentang implementasi tiruan, baca buku Martin Fowler Mocks Are Not Stubs .



Bercanda dan mengejek



Jest memiliki fitur jest.mockyang memungkinkan Anda mengejek seluruh modul yang Anda ganti. Dalam tutorial ini, saya fokus pada fitur ini, meskipun ada cara lain untuk mengganti objek di JavaScript.



Dalam buku Mastering React Test-Driven Development, saya menggunakan impor modul bernama ES6 untuk membuat tes ganda. Pendekatan ini memberikan sedikit lebih banyak fleksibilitas, tetapi terlihat sedikit lebih hackish.



Jest jest.mockDikatakan mengolok-olok memastikan tes Anda cepat dan tidak rapuh .



Meskipun ini benar, ini bukanlah alasan utama saya menggunakan ejekan.

Saya menggunakan ejekan karena mereka membantu saya menjaga tes saya tetap independen satu sama lain.



Untuk memahami mengapa ini terjadi, mari kita lihat sebuah contoh.



Kenapa moki?



Di bawah ini adalah daftar komponen BlogPageyang melakukan dua hal: mengambil iddari properti urldan kemudian menampilkan PostContentkomponen dengannya id.



const getPostIdFromUrl = url =>
  url.substr(url.lastIndexOf("/") + 1)

export const BlogPage = ({ url }) => {

  const id = getPostIdFromUrl(url)

  return (
    <PostContent id={id} />
  )
}




Bayangkan Anda menulis pengujian untuk komponen ini, dan semua pengujian Anda disertakan BlogPage.test.js, yang merupakan satu rangkaian pengujian yang mencakup komponen BlogPagedan PostContent.



Pada titik ini, Anda tidak perlu mengolok-olok belum: kita belum melihat PostContentitu belum, tetapi mengingat ukuran BlogPage, sebenarnya tidak ada kebutuhan untuk memiliki dua suite tes terpisah, karena BlogPageitu umumnya sederhana PostContent.



Sekarang bayangkan menambahkan fungsionalitas ke BlogPagey dan y PostContent. Sebagai pengembang berbakat, Anda menambahkan lebih banyak fitur setiap hari.



Menjadi lebih sulit untuk mempertahankan tes agar berfungsi. Setiap pengujian baru memiliki penyiapan yang lebih kompleks, dan rangkaian pengujian mulai menghabiskan lebih banyak waktu Anda - beban yang sekarang perlu didukung.

Ini adalah masalah umum dan saya melihatnya sepanjang waktu di basis kode React. Rangkaian pengujian yang bahkan perubahan paling sederhana pun akan mengakibatkan banyak pengujian gagal.



Salah satu solusinya adalah membagi rangkaian pengujian. Kami akan keluar BlogPage.test.jsdan membuat yang baru PostContent.test.jsyang seharusnya berisi tes khusus untuk PostContent. Ide dasarnya adalah bahwa fungsi apa pun yang ditempatkan di PostContentharus ditentukan PostContent.test.js, dan fungsi apa pun yang ditempatkan di BlogPage(seperti penguraian URL) harus dalam BlogPage.test.js.



Baik.



Tapi bagaimana jika renderingPostContent memiliki efek samping?



export const PostContent = ({ id }) => {
  const [ text, setText ] = useState("")

  useEffect(() => {
    fetchPostContent(id)
  }, [id])

  const fetchPostContent = async () => {
    const result = await fetch(`/post?id=${id}`)
    if (result.ok) {
      setText(await result.text())
    }
  }

  return <p>{text}</p>
};




Rangkaian pengujian BlogPage.test.jsharus menyadari efek sampingnya dan bersiap untuk menanganinya. Misalnya, dia harus menyiapkan fetchjawaban.



Ketergantungan yang kami coba hindari dengan memisahkan rangkaian pengujian kami masih ada.



Pengaturan pengujian kami sudah pasti menjadi lebih baik, tetapi pada akhirnya, tidak ada yang terjadi untuk membuat pengujian kami kurang rapuh.

Untuk ini kita membutuhkan rintisan (atau tiruan) PostContent.

Dan di bagian selanjutnya kita akan melihat bagaimana melakukan ini.



Apakah ini benar-benar perlu?



Ngomong-ngomong, beberapa kata tentang berpindah dari pengujian ujung ke ujung ke pengujian unit.



Memiliki tes ganda adalah indikator kunci bahwa Anda menulis tes unit.



Banyak penguji berpengalaman memulai proyek baru segera dengan pengujian unit (dan mengejek) karena mereka tahu bahwa saat basis kode mereka berkembang, mereka akan mengalami masalah ketidakstabilan pengujian.

Tes unit biasanya jauh lebih kecil daripada tes ujung ke ujung. Mereka bisa jadi sangat kecil sehingga seringkali tidak lebih dari tiga atau empat baris kode. Ini menjadikan mereka kandidat yang bagus untuk praktik pengkodean sosial seperti pemasangan dan pemrograman ensemble.


Bahkan ketika kami melakukan pengujian unit, pengujian ganda tidak selalu diperlukan - mereka hanyalah alat lain di suite Anda yang perlu Anda ketahui kapan dan bagaimana menerapkannya.



Di bagian selanjutnya, kita akan membahas teknik-teknik dasar mengejek .






All Articles