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
.
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 publik
{
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 adalahawaited
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.
async
dari tanda tangan metodeasync
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
Komentar yang paling membantu
@ploeh Pada dasarnya,
async
tidak cepat gagal. Perhatikan contoh berikut:```c#GuardedOpenGenericMethodReturningTaskResult(arg objek)
Tugas asinkron publik
{
if (arg == null) melempar ArgumentNullException baru(nameof(arg));
}
```
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 adalahawaited
dan pengecualian segera dilempar. Jadi tidak apa-apa bahwa prinsip "fast-fail" dilanggar dalam bentuk yang Anda harusawait
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.