Autofixture: Perlakukan delegasi sebagai Palsu dengan FakeItEasy

Dibuat pada 16 Feb 2018  ·  15Komentar  ·  Sumber: AutoFixture/AutoFixture

Sejauh yang saya tahu, AutoFixture secara otomatis memperlakukan antarmuka dan tipe abstrak sebagai mockable. Saya pikir itu adalah ide yang baik untuk memasukkan jenis delegasi dalam daftar ini juga.

enhancement good first issue

Komentar yang paling membantu

Dirilis di v4.2.0! Untuk mengaktifkan:
c# fixture.Customize(new AutoFakeItEasyCustomization { GenerateDelegates = true });

Semua 15 komentar

Pertama-tama, bisakah Anda mengklarifikasi kerangka kerja mengejek mana yang Anda gunakan? Kami memiliki beberapa integrasi (Moq, NSubsitute, FakeItEasy), jadi tidak jelas. Sejauh yang saya tahu, delegasi sudah didukung oleh integrasi Moq (setidaknya disebutkan di #742).

Juga sejauh yang saya tahu AutoFixture memiliki mekanisme pembuatan delegasi sendiri. Apakah Anda memiliki masalah dengan itu?

@zvirja saya menggunakan FakeItEasy. Jadi saya mengubah judul masalah
Kode berikut mengembalikan Palsu setelah penyesuaian diterapkan:
var myFake= fixture.Create<ISomeInterface>();

Namun yang berikut ini tidak:
var myFake= fixture.Create<Func<int,int>>();

Kode di atas baru saja mengembalikan delegasi tiruan yang tidak palsu.

Lebih jauh lagi, crash berikut dengan kesalahan:

var myFake= fixture.Create<Fake<Func<int,int>>>();

AutoFixture.ObjectCreationExceptionWithPath
HRHasil = 0x80131500
Message=AutoFixture tidak dapat membuat instance dari System.IntPtr karena pembuatannya tiba-tiba gagal dengan pengecualian. Silakan merujuk ke pengecualian dalam untuk menyelidiki akar penyebab kegagalan.

Jalur permintaan:
FakeItEasy.Fake 1[System.Func 2[System.Int32,System.Int32]]
metode IntPtr
System.IntPtr

Pesan pengecualian dalam:
AutoFixture.Kernel.IllegalRequestException: Permintaan untuk IntPtr terdeteksi. Ini adalah sumber daya yang tidak aman yang akan menghentikan proses jika digunakan, sehingga permintaan ditolak. Sumber umum permintaan IntPtr adalah permintaan untuk delegasi seperti Funcatau Tindakan. Jika ini masalahnya, solusi yang diharapkan adalah Menyesuaikan (Mendaftar atau Menyuntikkan) jenis yang menyinggung dengan menentukan strategi pembuatan yang tepat.

Sumber=
StackTrace:

Pengecualian Dalam 1:
IllegalRequestException: Permintaan untuk IntPtr terdeteksi. Ini adalah sumber daya yang tidak aman yang akan menghentikan proses jika digunakan, sehingga permintaan ditolak. Sumber umum permintaan IntPtr adalah permintaan untuk delegasi seperti Funcatau Tindakan. Jika ini masalahnya, solusi yang diharapkan adalah Menyesuaikan (Mendaftar atau Menyuntikkan) jenis yang menyinggung dengan menentukan strategi pembuatan yang tepat.

@OnurGumus Saya telah menyelidiki masalah ini secara singkat dan tampaknya FakeItEasy mendukung ejekan delegasi. Delegasi tidak disebutkan dalam dokumentasi mereka.

Saya juga telah menguji kode berikut dan gagal dengan pengecualian (yang membuktikan bahwa fitur tidak didukung):
c# A.Fake<Func<int, int>>();

Oleh karena itu, sepertinya AutoFixture tidak dapat melakukan sesuatu tentang hal itu juga.

Bisakah Anda menjelaskan perilaku yang diinginkan secara lebih rinci? Sangat mudah untuk mengejek delegasi, karena dapat ditentukan melalui ekspresi lambda primitif, jadi mengapa Anda membutuhkan tiruan?

@zvirja , FakeItEasy tentu mendukung Palsu untuk delegasi:
image

@blairconrad Bisakah Anda mencari beberapa menit dan menjelaskan ini? Apakah FakeItEasy mendukung ejekan para delegasi? Jika demikian, apa sintaksnya? Contoh saya di atas gagal untuk saya, tetapi itu bisa terjadi saya melewatkan sesuatu ... :confused:

Terima kasih :wink:

@zvirja , senang. Seperti yang dikatakan @OnurGumus , FakeItEasy akan dengan senang hati memalsukan delegasi (dan saya telah membuat masalah untuk mendokumentasikan ini).
Namun, AutoFakeItEasy tidak pernah repot dengan memalsukan delegasi.

Saat memalsukan Fake<Func<int, int>> , misalnya, FakeItEasyMethodQuery.SelectMethods gagal karena tidak mempertimbangkan kasus Fake<T> mana T adalah delegasi. Perubahan yang sangat naif di bawah ini memperbaiki ini.

@@ -33,7 +33,7 @@ namespace Ploeh.AutoFixture.AutoFakeItEasy
             }

             var fakeType = type.GetFakedType();
-            if (fakeType.IsInterface)
+            if (fakeType.IsInterface || fakeType.IsSubclassOf(typeof(Delegate)))
             {
                 return new[] { new ConstructorMethod(type.GetDefaultConstructor()) };
             }

Kemudian saya dapat membuat dan menggunakan Fake<Func<int, int>> .

Adapun untuk membuat Func<int, int> , saya mencobanya dengan cepat dan menemukan bahwa perlengkapan menggunakan DelegateGenerator untuk membuat delegasi (non-FakeItEasy).
Antara Anda dan saya, saya selalu bingung dengan arsitektur AutoFixture dan hubungan antara pembangun dan relai dan yang lainnya, tetapi saya dapat terus menjelajahi dan melihat di mana celahnya.

Saya kembali. Saya mungkin mengerti. FakeItEasyRelay ditambahkan ke kolektor residu perlengkapan, tetapi DelegateGenerator membuat delegasi terlebih dahulu.
Pencarian cepat tidak mengungkapkan cara memasukkan pembuat FakeItEasy sebelumnya dalam rantai, tetapi saya mungkin tidak terlihat benar.

Terlepas dari bagaimana ini berjalan, saya akan dengan senang hati mengirimkan PR untuk memungkinkan ejekan Fake<TDelegate> mana TDelegate adalah tipe delegasi.

@blairconrad sebagai pengguna FakeItEasy saya merindukan PR Anda :)

@blairconrad Terima kasih atas klarifikasi dan penyelidikan Anda! Saya baru saja memeriksa sekali lagi dan menemukan bahwa FakeItEasy memang membuat pemalsuan untuk delegasi. Kemungkinan, saya melewatkan sesuatu dalam tes saya sebelumnya

Adapun untuk membuat Func, saya mencobanya dengan cepat dan menemukan bahwa perlengkapan menggunakan DelegateGenerator untuk membuat delegasi (non-FakeItEasy).

Ya. Kami memiliki masalah yang sama persis dengan Moq - AutoFixture memotong permintaan tersebut sebelum ResidueCollectors memiliki kesempatan untuk bergabung.

Saya menyarankan untuk memperbaiki masalah ini dengan cara berikut:

  • Perluas kueri metode untuk mendukung permintaan Fake<Delegate> ;
  • Tambahkan kustomisasi baru, yang akan menambahkan relai ke koleksi Customizations , sehingga permintaan delegasi ditangani (direlay) _sebelum_ diproses oleh kernel AutoFixture. Artinya, fitur tersebut tidak akan diaktifkan secara default, namun pengguna dapat dengan mudah mengaktifkannya menggunakan kustomisasi yang telah ditentukan.

@blairconrad Selain itu, dapatkah Anda menjelaskan apa manfaat delegasi yang dipalsukan daripada yang dibuat oleh AutoFixture? Untuk saat ini hanya satu hal yang terlintas dalam pikiran saya - Anda dapat mengonfigurasinya menggunakan sintaks konfigurasi perpustakaan palsu.

Terima kasih, @zvirja.

Saya pikir Anda benar. Manfaat dari delegasi palsu adalah dapat dikonfigurasi menggunakan sintaks konfigurasi perpustakaan palsu.

Saya senang memperluas kueri metode untuk mendukung Fake<Delegate> , dan akan menambahkan penyesuaian tambahan seperti yang Anda katakan, tetapi bertanya-tanya: apakah yang mendukung Delegate cukup baik? Apa yang terjadi ketika bug yang dilaporkan berikutnya berharap IEnumerable atau Task atau IDictionary dipalsukan oleh FakeItEasy?

Oh, @zvirja telah meminta konfirmasi tentang sintaks untuk memalsukan delegasi. Sekarang telah digabungkan ke dalam dokumentasi FakeItEasy dengan FakeItEasy/FakeItEasy#1321, tetapi secara eksplisit:

```c#
var fakeDelegate = A.Fake>();

is the preferred syntax for clients, although "unnatural fakes" can be used:

```c#
var fakeDelegate = new Fake<Func<int, int>>();

Yang terakhir adalah bagaimana kelas FakeItEasyBuilder akan membuat Fake.

Fakta menyenangkan: delegasi palsu tidak didukung hingga versi 1.7.4257.42 (mungkin melakukan FakeItEasy/FakeItEasy@edb4f61d0db0a84b68c7a9395f2661a58579d34a). Secara pribadi, saya tidak masalah mengatakan "Anda tidak mendapatkan ini kecuali Anda menggunakan setidaknya versi FakeItEasy". @zvirja atau yang lain, apakah Anda menganggap ini masalah? Saya harus melakukan beberapa tipu daya dengan pengujian unit untuk memastikan kami tidak merusak pengujian AutoFakeItEasyUnitTest yang ada.
Kecuali jika Anda ingin memperbarui versi FakeItEasy minimum untuk perbaikan ini. Saya mungkin tidak akan melakukannya, terutama karena meminta delegasi akan gagal pada versi itu.

@blairconrad Terima kasih banyak atas pekerjaan Anda!

@zvirja atau yang lain, apakah Anda menganggap ini masalah?

Tidak ada sama sekali. Menurut SemVer yang kami ikuti di sini, kami tidak diizinkan untuk mengubah versi ketergantungan dalam versi utama yang sama. Oleh karena itu, saya akan mengatakan bahwa langkah yang tepat adalah menambahkan dukungan untuk versi FakeItEasy yang mendukung fitur tersebut. Nanti kami mungkin ingin menjatuhkan dukungan 1.x di v5 (untuk konsistensi), tetapi itu hanya akan terjadi di masa mendatang.

Mengonversi masalah ini menjadi fitur, karena kami setuju untuk melanjutkannya (dan FakeItEasy mendukung delegasi).

Dirilis di v4.2.0! Untuk mengaktifkan:
c# fixture.Customize(new AutoFakeItEasyCustomization { GenerateDelegates = true });

Apakah halaman ini membantu?
0 / 5 - 0 peringkat