Rumah pembangunan bahagian belakang Golang Memudahkan Ujian Penyepaduan Go dengan gofacto: Kilang Berkuasa untuk Data Olok-olok

Memudahkan Ujian Penyepaduan Go dengan gofacto: Kilang Berkuasa untuk Data Olok-olok

Aug 27, 2024 am 06:00 AM

Simplifying Go Integration Tests with gofacto: A Powerful Factory for Mock Data

Menulis ujian integrasi dengan pangkalan data adalah penting untuk pembangunan aplikasi web, kerana ia meningkatkan keyakinan dalam kod kami dan memastikan aplikasi kami berfungsi seperti yang diharapkan. Walau bagaimanapun, menyediakan data olok-olok untuk ujian ini boleh menjadi mencabar, terutamanya dalam Go, yang tidak mempunyai pendekatan terbina dalam atau perpustakaan standard untuk tugasan ini. Artikel ini memperkenalkan perpustakaan gofacto, yang memudahkan proses membina data palsu dan memasukkannya ke dalam pangkalan data untuk ujian integrasi Go.

 

Apa itu gofacto?

gofacto ialah perpustakaan Go yang memudahkan penciptaan dan penyisipan data palsu ke dalam pangkalan data. Ia menyediakan pendekatan intuitif untuk mentakrifkan skema data dan mengendalikan sisipan pangkalan data dengan cekap. Dengan gofacto, pembangun boleh menyediakan data ujian dengan cepat tanpa beban menulis kod boilerplate yang meluas, membolehkan mereka menumpukan pada menulis ujian yang bermakna.

 

Sebelum menggunakan gofacto

Mari lihat perkara yang biasa kami lakukan semasa menulis ujian penyepaduan dengan pangkalan data dalam Go. Katakan kita mempunyai jadual bernama pengguna dalam pangkalan data, dan ia mempunyai skema berikut:

CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
Salin selepas log masuk

Katakan kita ingin menguji fungsi bernama getUserByID yang mendapatkan semula pengguna dengan IDnya daripada jadual pengguna. Untuk menguji fungsi ini, kita perlu menyediakan beberapa data olok-olok dalam pangkalan data sebelum menguji fungsi ini. Begini cara biasa kami melakukannya:

type User struct {
    ID      int
    Gender  string
    Name    string
    Email   string
}

// build and insert mock user
mockUser := User{
    ID:     1,
    Gender: "male",
    Name:   "Alice",
    Email:  "aaa@gmail.com",
}
err := insertToDB(mockUser)

// action
result, err := getUserByID(mockUser.ID)

// assertion
// ...
Salin selepas log masuk

insertToDB ialah fungsi yang memasukkan data palsu ke dalam pangkalan data. Ia mungkin menjadi sangat rumit jika kita menggunakan pertanyaan sql mentah.

Pendekatan ini nampaknya boleh diurus kerana skemanya mudah dan kami hanya berurusan dengan satu jadual.

Mari kita lihat kesnya apabila kita berurusan dengan dua jadual, pengguna dan siaran. Setiap pengguna boleh mempunyai berbilang siaran dan hubungan antara jadual diwujudkan oleh medan user_id dalam jadual siaran.

CREATE TABLE posts (
    id INT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
Salin selepas log masuk

Katakan kita ingin menguji fungsi bernama getPostsByUserID yang mendapatkan semula semua siaran dengan ID pengguna daripada jadual siaran.

type Post struct {
  ID      int
  UserID  int
  Title   string
  Content string
}

// build and insert mock user
mockUser := User{
    ID:     1,
    Gender: "male",
    Name:   "Alice",
    Email:  "aaa@gmail.com",
}
err := insertToDB(mockUser)

// build and insert mock post
mockPost1 := Post{
  ID:      1,
  UserID:  mockUser.ID, // manually set the foreign key
  Title:   "Post 1",
  Content: "Content 1",
}
err = insertToDB(mockPost1)

// build and insert mock post
mockPost2 := Post{
  ID:      2,
  UserID:  mockUser.ID, // manually set the foreign key
  Title:   "Post 2",
  Content: "Content 2",
}
err = insertToDB(mockPost2)

// action
result, err := getPostsByUserID(mockUser.ID)

// assertion
// ...
Salin selepas log masuk

Kami mula-mula membuat pengguna dan kemudian membuat dua siaran untuk pengguna tersebut. Berbanding dengan contoh sebelumnya, ia menjadi lebih kompleks kerana kita berurusan dengan dua jadual dan mewujudkan hubungan antara mereka.

Bagaimana jika kita mahu membuat berbilang siaran dengan pengguna yang berbeza?
Kami perlu mencipta pengguna untuk setiap siaran dan ia memerlukan lebih banyak kod.

// build and insert mock user
mockUser1 := User{
  ID:    1,
  Gender: "male",
  Name:  "Alice",
  Email: "aaa@gmail.com",
}
err := insertToDB(mockUser1)

// build and insert mock user
mockUser2 := User{
  ID:  2,
  Gender: "female",
  Name:  "Bob",
  Email: "bbb@gmail.com",
}
err = insertToDB(mockUser2)

// build and insert mock post
mockPost1 := Post{
  ID:      1,
  UserID:  mockUser1.ID, // manually set the foreign key
  Title:   "Post 1",
  Content: "Content 1",
}
err = insertToDB(mockPost1)

// build and insert mock post
mockPost2 := Post{
  ID:      2,
  UserID:  mockUser2.ID, // manually set the foreign key
  Title:   "Post 2",
  Content: "Content 2",
}
err = insertToDB(mockPost2)

// action
result, err := getPostsByUserID(mockUser1.ID)

// assertion
// ...
Salin selepas log masuk

Ia menjadi lebih kompleks dan terdedah kepada ralat apabila kami perlu membuat berbilang data olok-olok dengan pengguna dan siaran yang berbeza.

Juga ambil perhatian bahawa kami hanya menggunakan skema mudah untuk tujuan demonstrasi, kod akan menjadi lebih kompleks dalam aplikasi dunia sebenar.

 

Apakah masalahnya?

Dalam contoh di atas, terdapat beberapa masalah:

  • Tulis banyak kod boilerplate untuk menyediakan data palsu dalam pangkalan data
    • Kadang-kadang, kita tidak kisah apa nilai medan, kita cuma perlu pastikan ada nilai yang betul dalam setiap medan.
  • Kod keras nilai ID dalam data palsu
    • Adalah bukan amalan yang baik untuk mengekodkan keras nilai ID dalam data palsu kerana ID biasanya dinaikkan secara automatik dalam pangkalan data.
  • Mewujudkan perhubungan antara jadual secara manual
    • Ini menjadikan kod ujian menyusahkan dan terdedah kepada ralat, terutamanya apabila mencipta data palsu dengan berbilang jadual berkaitan.

 

Menggunakan gofacto

Sekarang, mari lihat bagaimana perpustakaan gofacto boleh membantu kami menyelesaikan masalah di atas, dan menjadikan keseluruhan proses lebih mudah.

Mari lihat contoh pertama dengan jadual pengguna.

// initialize a factory with User struct (also use `WithDB` to pass the database connection)
f := gofacto.New(User{}).WithDB(db)

// build and insert mock user
mockUser, err := f.Build(ctx).Insert()

// action
result, err := getUserByID(mockUser.ID)

// assertion
// ...
Salin selepas log masuk

Untuk menggunakan gofacto, kami mula-mula menggunakan fungsi Baharu untuk memulakan kilang baharu dengan Pengguna. Kerana kita perlu memasukkan data ke dalam pangkalan data, menggunakan WithDB untuk menghantar sambungan pangkalan data ke kilang.
Kemudian, kami menggunakan fungsi Bina untuk membina data olok-olok. Fungsi Sisipan memasukkan data olok-olok ke dalam pangkalan data dan mengembalikan data olok-olok yang telah dimasukkan ke dalam pangkalan data dengan ID yang ditambah secara automatik.

Ambil perhatian bahawa semua medan data olok-olok dijana secara rawak secara lalai. Tidak mengapa dalam kes ini kerana kami tidak mengambil berat tentang nilai medan.

Sekiranya kita ingin menentukan nilai medan, kita boleh menggunakan fungsi Tulis Ganti untuk menetapkan nilai medan.

mockUser, err := f.Build(ctx).Overwrite(User{Gender: "male"}).Insert()
// mockUser.Gender == "male"
Salin selepas log masuk

Apabila menggunakan fungsi Tulis Ganti, kita hanya perlu menentukan medan yang ingin kita timpa. Medan lain akan dijana secara rawak seperti biasa.

Mari kita lihat kes di mana kita ingin membuat berbilang siaran dengan seorang pengguna.
Untuk membuat gofacto mengetahui hubungan antara jadual, kita perlu menentukan tag yang betul dalam struct.

type Post struct {
    ID      int
    UserID  int       `gofacto:"foreignKey,struct:User"`
    Title   string
    Content string
}
Salin selepas log masuk

The tag tells gofacto that the UserID field is a foreign key that references the ID field of the User struct.

Now, we can create multiple posts with one user easily.

mockUser := User{}
mockPosts, err := f.BuildList(ctx, 2).WithOne(&mockUser).Insert() // must pass pointer to the struct to `WithOne`
// mockPosts[0].UserID == mockUser.ID
// mockPosts[1].UserID == mockUser.ID

// action
result, err := getPostsByUserID(mockUser.ID)

// assertion
// ...
Salin selepas log masuk

In order to create multiple posts, we use BuildList function with the number of posts that we want to create. Then, we use WithOne function to specify that all the posts belong to one user. The Insert function returns a list of posts that have been inserted into the database with the auto-incremented ID.

gofacto library makes sure all the fields are correctly set randomly, and the relationship between the tables is correctly established.

Let's see the case where we want to create multiple posts with different users.

mockUser1 := User{}
mockUser2 := User{}
mockPosts, err := f.BuildList(ctx, 2).WithMany([]interface{}{&mockUser1, &mockUser2}).Insert()
// mockPosts[0].UserID == mockUser1.ID
// mockPosts[1].UserID == mockUser2.ID

// action
result, err := getPostsByUserID(mockUser1.ID)

// assertion
// ...
Salin selepas log masuk

We use WithMany function to specify that each post is associated with a different user.

 

Summary

We've seen how gofacto simplifies writing integration tests with databases in Go. It reduces boilerplate code and makes it easier to prepare mock data with multiple tables and establish relationships between them. Most importantly, gofacto abstracts away the complexity of preparing mock data, allowing developers to focus on writing meaningful tests. To start using gofacto in your Go projects, visit the GitHub repository for installation instructions and more detailed documentation.

 

Feedback and Further Development

As a new library developer, I'd love to hear your thoughts on gofacto! Any feedback, advice or criticism is appreciated. If you use it in your Go projects, please share your experience. Found a bug or have an idea? Open an issue on the gofacto GitHub repo. Want to contribute code? Pull requests are welcome! Your feedback and contributions will help improve gofacto and benefit the Go community. Thanks for checking it out!

Atas ialah kandungan terperinci Memudahkan Ujian Penyepaduan Go dengan gofacto: Kilang Berkuasa untuk Data Olok-olok. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

<🎜>: Bubble Gum Simulator Infinity - Cara Mendapatkan dan Menggunakan Kekunci Diraja
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Cara Membuka Kunci Cangkuk Bergelut
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Sistem Fusion, dijelaskan
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1668
14
Tutorial PHP
1273
29
Tutorial C#
1256
24
Golang vs Python: Prestasi dan Skala Golang vs Python: Prestasi dan Skala Apr 19, 2025 am 12:18 AM

Golang lebih baik daripada Python dari segi prestasi dan skalabiliti. 1) Ciri-ciri jenis kompilasi Golang dan model konkurensi yang cekap menjadikannya berfungsi dengan baik dalam senario konvensional yang tinggi. 2) Python, sebagai bahasa yang ditafsirkan, melaksanakan perlahan -lahan, tetapi dapat mengoptimumkan prestasi melalui alat seperti Cython.

Golang dan C: Konvensyen vs kelajuan mentah Golang dan C: Konvensyen vs kelajuan mentah Apr 21, 2025 am 12:16 AM

Golang lebih baik daripada C dalam kesesuaian, manakala C lebih baik daripada Golang dalam kelajuan mentah. 1) Golang mencapai kesesuaian yang cekap melalui goroutine dan saluran, yang sesuai untuk mengendalikan sejumlah besar tugas serentak. 2) C Melalui pengoptimuman pengkompil dan perpustakaan standard, ia menyediakan prestasi tinggi yang dekat dengan perkakasan, sesuai untuk aplikasi yang memerlukan pengoptimuman yang melampau.

Bermula dengan Go: Panduan Pemula Bermula dengan Go: Panduan Pemula Apr 26, 2025 am 12:21 AM

GoisidealforbeginnersandSuekableforcloudandnetworkservicesduetoitssimplicity, kecekapan, danconcurrencyfeatures.1) installgofromtheofficialwebsiteandverifywith'goversion'.2)

Golang vs C: Perbandingan Prestasi dan Kelajuan Golang vs C: Perbandingan Prestasi dan Kelajuan Apr 21, 2025 am 12:13 AM

Golang sesuai untuk pembangunan pesat dan senario serentak, dan C sesuai untuk senario di mana prestasi ekstrem dan kawalan peringkat rendah diperlukan. 1) Golang meningkatkan prestasi melalui pengumpulan sampah dan mekanisme konvensional, dan sesuai untuk pembangunan perkhidmatan web yang tinggi. 2) C mencapai prestasi muktamad melalui pengurusan memori manual dan pengoptimuman pengkompil, dan sesuai untuk pembangunan sistem tertanam.

Impak Golang: Kelajuan, Kecekapan, dan Kesederhanaan Impak Golang: Kelajuan, Kecekapan, dan Kesederhanaan Apr 14, 2025 am 12:11 AM

Goimpactsdevelopmentpositivielythroughspeed, efficiency, andsimplicity.1) Speed: goCompilesquicklyandrunsefficiently, idealforlargeproject.2) Kecekapan: ITSComprehensivestandardlibraryraryrarexternaldependencies, enhingdevelyficiency.

C dan Golang: Apabila prestasi sangat penting C dan Golang: Apabila prestasi sangat penting Apr 13, 2025 am 12:11 AM

C lebih sesuai untuk senario di mana kawalan langsung sumber perkakasan dan pengoptimuman prestasi tinggi diperlukan, sementara Golang lebih sesuai untuk senario di mana pembangunan pesat dan pemprosesan konkurensi tinggi diperlukan. Kelebihan 1.C terletak pada ciri-ciri perkakasan dan keupayaan pengoptimuman yang tinggi, yang sesuai untuk keperluan berprestasi tinggi seperti pembangunan permainan. 2. Kelebihan Golang terletak pada sintaks ringkas dan sokongan konvensional semulajadi, yang sesuai untuk pembangunan perkhidmatan konvensional yang tinggi.

Golang vs Python: Perbezaan dan Persamaan Utama Golang vs Python: Perbezaan dan Persamaan Utama Apr 17, 2025 am 12:15 AM

Golang dan Python masing -masing mempunyai kelebihan mereka sendiri: Golang sesuai untuk prestasi tinggi dan pengaturcaraan serentak, sementara Python sesuai untuk sains data dan pembangunan web. Golang terkenal dengan model keserasiannya dan prestasi yang cekap, sementara Python terkenal dengan sintaks ringkas dan ekosistem perpustakaan yang kaya.

Golang dan C: Perdagangan dalam prestasi Golang dan C: Perdagangan dalam prestasi Apr 17, 2025 am 12:18 AM

Perbezaan prestasi antara Golang dan C terutamanya ditunjukkan dalam pengurusan ingatan, pengoptimuman kompilasi dan kecekapan runtime. 1) Mekanisme pengumpulan sampah Golang adalah mudah tetapi boleh menjejaskan prestasi, 2) Pengurusan memori manual C dan pengoptimuman pengkompil lebih cekap dalam pengkomputeran rekursif.

See all articles