Apakah ada perpustakaan atau metode untuk mengejek sistem file dalam C # untuk menulis tes unit? Dalam kasus saya saat ini, saya memiliki metode yang memeriksa apakah file tertentu ada dan membaca tanggal pembuatan. Saya mungkin membutuhkan lebih dari itu di masa depan.
c#
unit-testing
mocking
pupeno
sumber
sumber
Jawaban:
Sunting: Instal paket NuGet
System.IO.Abstractions
.Paket ini tidak ada ketika jawaban ini awalnya diterima. Jawaban asli diberikan untuk konteks historis di bawah ini:
sumber
Pustaka imajiner ini ada sekarang, ada paket NuGet untuk System.IO.Abstractions , yang memisahkan abstrak namespace System.IO.
Ada juga satu set alat bantu pengujian, System.IO.Abstractions.TestingHelpers yang - pada saat penulisan - hanya dilaksanakan sebagian, tetapi merupakan titik awal yang sangat baik.
sumber
Anda mungkin harus membuat kontrak untuk menentukan hal-hal apa yang Anda butuhkan dari sistem file dan kemudian menulis pembungkus di sekitar fungsi-fungsi itu. Pada titik itu Anda bisa mengejek atau mematikan implementasi.
Contoh:
sumber
Rekomendasi saya adalah menggunakan http://systemwrapper.codeplex.com/ karena menyediakan pembungkus untuk jenis yang paling banyak digunakan di System namespace
sumber
Saya menemukan solusi berikut untuk ini:
Saya akhirnya menggunakan semua metode di atas, tergantung pada apa yang saya tulis. Tetapi sebagian besar waktu saya akhirnya berpikir abstraksi salah ketika saya menulis unit test yang mengenai IO.
sumber
Dengan menggunakan System.IO.Abstractions dan System.IO.Abstractions.TestingHelpers seperti itu:
Di Kelas Tes Anda, Anda menggunakan MockFileSystem () untuk mengejek file dan Anda instanciate ManageFile seperti:
sumber
Anda dapat melakukannya dengan menggunakan Microsoft Fakes tanpa perlu mengubah basis kode Anda misalnya karena sudah dibekukan.
Pertama-tama hasilkan perakitan palsu untuk System.dll - atau paket lainnya dan kemudian mengejek pengembalian yang diharapkan seperti pada:
sumber
Akan sulit untuk mengolok-olok sistem file dalam suatu pengujian karena .NET file API tidak benar-benar didasarkan pada antarmuka atau kelas yang dapat diperluas yang dapat diejek.
Namun, jika Anda memiliki lapisan fungsional Anda sendiri untuk mengakses sistem file, Anda bisa mengejeknya dalam unit test.
Sebagai alternatif untuk mengejek, pertimbangkan untuk hanya membuat folder dan file yang Anda butuhkan sebagai bagian dari pengaturan pengujian Anda, dan menghapusnya dalam metode teardown Anda.
sumber
Saya tidak yakin bagaimana Anda akan mengejek sistem file. Apa yang bisa Anda lakukan adalah menulis pengaturan fixture tes yang membuat folder, dll. Dengan struktur yang diperlukan untuk tes. Metode teardown akan membersihkannya setelah tes berjalan.
Diedit untuk menambahkan: Dalam memikirkan ini sedikit lagi, saya tidak berpikir Anda ingin mengejek sistem file untuk menguji metode jenis ini. Jika Anda mengejek sistem file untuk mengembalikan nilai true jika ada file tertentu dan menggunakannya dalam pengujian metode yang memeriksa apakah file itu ada, maka Anda tidak menguji apa-apa. Di mana mengolok-olok sistem file akan berguna adalah jika Anda ingin menguji metode yang memiliki ketergantungan pada sistem file tetapi aktivitas sistem file tidak terpisahkan dengan metode yang diuji.
sumber
Untuk menjawab pertanyaan spesifik Anda: Tidak, tidak ada perpustakaan yang akan memungkinkan Anda untuk mengejek panggilan file I / O (yang saya tahu). Ini berarti bahwa unit "yang benar" yang menguji tipe Anda akan mengharuskan Anda mempertimbangkan batasan ini saat menentukan tipe Anda.
Catatan samping cepat tentang cara saya mendefinisikan unit test "tepat". Saya percaya bahwa unit test harus mengkonfirmasi bahwa Anda mendapatkan output yang diharapkan (baik pengecualian, memanggil metode, dll) memberikan input yang dikenal. Ini memungkinkan Anda untuk mengatur kondisi pengujian unit Anda sebagai serangkaian input dan / atau status input. Cara terbaik yang saya temukan untuk melakukan ini adalah menggunakan layanan berbasis antarmuka dan injeksi ketergantungan sehingga setiap tanggung jawab eksternal untuk suatu tipe diberikan melalui antarmuka yang dilewatkan melalui konstruktor atau properti.
Jadi, dengan mengingat hal ini, kembalilah ke pertanyaan Anda. Saya telah mengejek panggilan sistem file dengan membuat
IFileSystemService
antarmuka bersama denganFileSystemService
implementasi yang hanya fasad atas metode sistem file mscorlib. Kode saya kemudian menggunakan jenisIFileSystemService
daripada mscorlib. Ini memungkinkan saya untuk memasukkan standar sayaFileSystemService
ketika aplikasi sedang berjalan atau mengejekIFileSystemService
dalam unit test saya. Kode aplikasinya sama terlepas dari bagaimana dijalankannya, tetapi infrastruktur yang mendasarinya memungkinkan kode itu untuk dengan mudah diuji.Saya akan mengakui bahwa itu adalah rasa sakit untuk menggunakan pembungkus di sekitar objek sistem file mscorlib tetapi, dalam skenario khusus ini, layak untuk bekerja ekstra karena pengujian menjadi jauh lebih mudah dan lebih dapat diandalkan.
sumber
Membuat antarmuka dan mengejeknya untuk pengujian adalah cara terbersih untuk dilakukan. Namun, sebagai alternatif, Anda dapat melihat kerangka Microsoft Moles .
sumber
Solusi umum adalah menggunakan beberapa API sistem file abstrak (seperti Apache Commons VFS untuk Java): semua logika aplikasi menggunakan API dan unit test dapat mengejek sistem file nyata dengan implementasi rintisan (emulasi dalam memori atau sesuatu seperti itu).
Untuk C # API serupa ada: NI.Vfs yang sangat mirip dengan Apache VFS V1. Ini berisi implementasi standar baik untuk sistem file lokal dan sistem file dalam memori (yang terakhir dapat digunakan dalam unit test dari kotak).
sumber
Kami saat ini menggunakan mesin data berpemilik dan API-nya tidak diekspos sebagai antarmuka sehingga kami sulit menguji unit kode akses data kami. Lalu aku pergi dengan pendekatan Matt dan Joseph juga.
sumber
Saya akan pergi dengan respons Jamie Ide. Jangan mencoba mengejek hal-hal yang tidak Anda tulis. Akan ada segala macam ketergantungan yang tidak Anda ketahui - kelas tertutup, metode non virtual dll.
Pendekatan lain adalah membungkus metode yang sesuai dengan sesuatu yang dapat dipermainkan. misalnya membuat kelas bernama FileWrapper yang memungkinkan akses ke metode File tetapi merupakan sesuatu yang dapat Anda tiru.
sumber