Autofixture: Buat GuardClauseAssertion alternatif yang mendukung metode yang ditandai dengan `async`.

Dibuat pada 1 Mar 2019  ·  12Komentar  ·  Sumber: AutoFixture/AutoFixture

Seperti yang dibahas di #268, kelas GuardClauseAssertion tidak menunggu tugas untuk diselesaikan, sehingga tidak dapat memvalidasi metode cepat non-

Ini sepenuhnya dapat dimengerti, karena gagal cepat memang merupakan pilihan terbaik. Namun demikian, tampaknya tidak mungkin untuk menerapkan perilaku cepat gagal ketika berhadapan dengan metode yang ditandai dengan kata kunci async .

enhancement

Komentar yang paling membantu

@ploeh Pada dasarnya, async tidak cepat gagal. Perhatikan contoh berikut:

```c#
Tugas asinkron publikGuardedOpenGenericMethodReturningTaskResult(arg objek)
{
if (arg == null) melempar ArgumentNullException baru(nameof(arg));

await Task.Yield();

return default;

}
```

Metode ini tidak melempar jika Anda menyebutnya akan null . Sebaliknya, Task gagal dikembalikan. Oleh karena itu, GuardClauseAssertion itu bentuknya saat ini gagal dan mengeluh tentang klausa penjaga yang hilang.

Dalam aplikasi nyata hampir semua kode adalah async , oleh karena itu setiap doa adalah awaited dan pengecualian segera dilempar. Jadi tidak apa-apa bahwa prinsip "fast-fail" dilanggar dalam bentuk yang Anda harus await Task untuk melihat pengecualian.

Tentu saja, Anda dapat menulis ulang kode untuk membuatnya gagal segera (buat fungsi pribadi dengan kata kunci async dan pindahkan semua logika di sana), tetapi tidak ada cara praktis untuk melakukannya.

Semua 12 komentar

tampaknya tidak mungkin untuk menerapkan perilaku _fail fast_ ketika berhadapan dengan metode yang ditandai dengan kata kunci async .

Bagaimana? Bisakah Anda memberikan contoh?

@ploeh Pada dasarnya, async tidak cepat gagal. Perhatikan contoh berikut:

```c#
Tugas asinkron publikGuardedOpenGenericMethodReturningTaskResult(arg objek)
{
if (arg == null) melempar ArgumentNullException baru(nameof(arg));

await Task.Yield();

return default;

}
```

Metode ini tidak melempar jika Anda menyebutnya akan null . Sebaliknya, Task gagal dikembalikan. Oleh karena itu, GuardClauseAssertion itu bentuknya saat ini gagal dan mengeluh tentang klausa penjaga yang hilang.

Dalam aplikasi nyata hampir semua kode adalah async , oleh karena itu setiap doa adalah awaited dan pengecualian segera dilempar. Jadi tidak apa-apa bahwa prinsip "fast-fail" dilanggar dalam bentuk yang Anda harus await Task untuk melihat pengecualian.

Tentu saja, Anda dapat menulis ulang kode untuk membuatnya gagal segera (buat fungsi pribadi dengan kata kunci async dan pindahkan semua logika di sana), tetapi tidak ada cara praktis untuk melakukannya.

Dalam aplikasi nyata hampir semua kode adalah async , oleh karena itu setiap doa adalah awaited dan pengecualian segera dilempar.

Itu poin yang adil; Saya menerima argumen itu.

Saya terkadang teralihkan ketika seseorang menegaskan atau menyiratkan (dengan sedikit bukti) bahwa ada sesuatu yang _tidak mungkin_...

Saya terkadang teralihkan ketika seseorang menegaskan atau menyiratkan (dengan sedikit bukti) bahwa ada sesuatu yang tidak mungkin...

Ya, itu cukup adil

Sekarang biarkan saya mencoba berpikir bagaimana saya bisa mendesain ulang GuardClauseAssertion agar tidak memiliki flag boolean - saya juga tidak menyukainya, jujur ​​saja. Sampai jumpa di PR.

Sekarang coba saya pikirkan bagaimana saya bisa mendesain ulang GuardClauseAssertion agar tidak memiliki flag boolean

Saya akan berpikir bahwa, seperti yang disarankan @moodmosaic , kelas baru mungkin merupakan desain yang lebih baik. Saya belum melihat masalah ini secara mendalam, jadi saya berhak untuk salah

Berikut adalah solusi yang saya gunakan.

  1. Hapus kata kunci async dari tanda tangan metode
  2. Buat metode bersarang dengan kata kunci async
  3. Letakkan klausa penjaga di bagian luar metode
  4. Panggil metode bersarang dan kembalikan hasilnya

Contoh:

public Task<int> GetNumberAsync(MyObject obj)
{
    // Fail-fast behavior
    if (request is null)
        throw new ArgumentNullException(nameof(obj));

    async Task<int> work()
    {
        var items = await obj.GetItemsAsync(); // whatever you need to call
        return items.Count();
    }

    return work();
}

Ini telah menjadi solusi yang baik bagi saya. Terima kasih atas bantuan Anda.

@mniak Menarik untuk mendapatkan contoh nyata dari apa yang disarankan @zvirja di sini .

Secara pribadi saya tidak terlalu menyukainya karena kami mencemari metode dengan "trik" untuk kepentingan kerangka pengujian, yang baunya sangat buruk bagi saya dan saya tidak ingin tim saya menggunakan pola ini.

Tetap terbuka untuk mengimplementasikan dukungan dengan cara asli. Satu hari. Dalam waktu dekat. Atau hanya satu hari.

Hai. Kami tersandung masalah ini dan terkejut bahwa tidak ada solusi yang baik sejauh ini.
Apakah ada alasan untuk tidak mengimplementasikan kelas baru untuk ini?
Saya tidak tahu detail bagian dalam AutoFixture tetapi jika kita memiliki MethodInfo yang tersedia di dalam kelas GuardClauseAssertion untuk Method-to-Test kita dapat melihat CustomAttributes dan mengidentifikasi apakah itu metode Async atau tidak (https:/ /stackoverflow.com/a/20350646). Jadi, mungkin, sakelar (bool vs. kelas baru) bahkan tidak diperlukan.

@zvirja @aivascu bisakah kita mempertimbangkan kembali ini? Saya benar-benar tidak mengerti mengapa pada tahun 2021 metode async tidak dapat diuji dengan benar.

@Kralizek jika saya membaca situasi dengan benar, permintaan belum ditolak, dan bahkan ada PR yang memperbaikinya.
Saya telah melihat sekilas PR dan saya harus mengatakan bahwa saya setuju dengan umpan balik yang diterimanya.
Jadi satu-satunya yang tersisa adalah menerapkan umpan balik atau mengajukan PR baru dengan umpan balik yang diterapkan.

Saya tidak bisa melihat PR tertaut di aplikasi seluler

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

zvirja picture zvirja  ·  8Komentar

mjfreelancing picture mjfreelancing  ·  4Komentar

zvirja picture zvirja  ·  3Komentar

tomasaschan picture tomasaschan  ·  3Komentar

ecampidoglio picture ecampidoglio  ·  7Komentar