Menguji apakah kelas memiliki atribut?

101

Saya mencoba melakukan sedikit pengembangan Test-First, dan saya mencoba memverifikasi bahwa kelas saya ditandai dengan atribut:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Bagaimana saya menguji unit bahwa kelas memiliki atribut yang ditugaskan padanya?

JoshRivers
sumber

Jawaban:

123

Periksa itu

Attribute.GetCustomAttribute(typeof(ScheduleController),
    typeof(SubControllerActionToViewDataAttribute))

bukan nol ( Assert.IsNotNullatau serupa)

(alasan saya menggunakan ini daripada IsDefinedseringnya saya ingin memvalidasi beberapa properti atribut juga ....)

Marc Gravell
sumber
6
untuk hanya memeriksa apakah atribut ada, yang biasanya merupakan semua yang diperlukan untuk atribut tanpa parameter / properti, lebih murah untuk menggunakan .IsDefined, karena ini akan meminta metadata, dan tidak menghilangkan dan membuat instance objek atribut.
Lasse V. Karlsen
1
Seperti poin tentang IsDefined yang lebih murah ... tetapi dalam banyak kasus (dan dalam pengujian unit tertentu) Anda tidak mungkin melihat perbedaannya. Mungkin jika itu adalah loop ketat dalam kode produksi ...
Marc Gravell
@ Marc- Saya setuju tentang bahwa perbedaan kinerja mungkin tidak akan terlihat dalam pengujian unit. Saya akan mendapatkan atribut jika saya perlu menggunakannya, yang seperti yang Anda katakan adalah skenario dalam banyak kasus. Saya baru-baru ini menggunakan IsDefined dalam kerangka yang saya tulis untuk mengecualikan kolom dalam dropdown bidang yang dapat diurutkan - ini bekerja dengan baik karena saya tidak perlu menggunakan atribut itu sendiri.
RichardOD
Bagaimana kita bisa menguji yang sama untuk suatu metode?
Manvinder Singh
80

Hal yang sama biasanya Anda periksa atribut di kelas.

Berikut beberapa contoh kode.

typeof(ScheduleController)
.IsDefined(typeof(SubControllerActionToViewDataAttribute), false);

Saya pikir dalam banyak kasus pengujian keberadaan atribut dalam pengujian unit salah. Karena saya belum menggunakan fungsionalitas sub pengontrol MVC contrib, saya tidak dapat berkomentar apakah itu sesuai dalam kasus ini.

RichardOD
sumber
Apakah memberi +1 dan kemudian melihat kesalahan. Ini harus .IsDefined (typeof (Type), false);
Alexander Beletsky
@alexanderb Anda tentu saja benar. Saya telah memperbarui jawaban saya sekarang. Saya tidak harus memeriksa jawaban saya terhadap kompiler pada saat itu! Terima kasih telah menunjukkan kesalahannya
RichardOD
10
pendekatan ini lebih cepat dari sebelumnya
Slava
18

Dimungkinkan juga untuk menggunakan obat generik untuk ini:

var type = typeof(SomeType);
var attribute = type.GetCustomAttribute<SomeAttribute>();

Dengan cara ini Anda tidak perlu lagi typeof(...), yang dapat membuat kode lebih bersih.

Kroltan
sumber
Ini tidak berhasil untuk saya. Yang using.. apakah saya hilang?
@Scanzy Saya tidak yakin, apakah Anda tidak menggunakan IDE? (Biasanya mereka menyarankan yang benar using) Kesalahan apa yang Anda dapatkan?
Kroltan
1
ok, di sini saya menemukan GetCustomAttribute<SomeAttribute>metode ini tersedia dari .NET 4.5 dan IDE saya disetel ke 3.5 jadi semuanya jelas sekarang
9

Saya tahu utas ini benar-benar tua, tetapi jika seseorang tersandung di atasnya, Anda mungkin menemukan proyek kelancaran pernyataan sangat nyaman untuk melakukan pernyataan semacam ini.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
Aleksey L.
sumber