Kiểm tra xem một lớp có thuộc tính không?


100

Tôi đang cố gắng thực hiện một chút phát triển Test-First và tôi đang cố gắng xác minh rằng các lớp của tôi được đánh dấu bằng thuộc tính:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Làm cách nào để kiểm tra đơn vị xem lớp có gán thuộc tính đó cho nó không?

Câu trả lời:


122

kiểm tra xem

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

không rỗng ( Assert.IsNotNullhoặc tương tự)

(lý do tôi sử dụng điều này thay vì IsDefinedlà hầu hết các lần tôi cũng muốn xác thực một số thuộc tính của thuộc tính ....)


6
để chỉ kiểm tra xem thuộc tính có hiện diện hay không, thường là tất cả những gì cần thiết cho các thuộc tính không tham số / không thuộc tính, sẽ rẻ hơn khi sử dụng .IsDefined, vì nó sẽ truy vấn siêu dữ liệu và không giải mã hóa và khởi tạo đối tượng thuộc tính.
Lasse V. Karlsen

1
Cũng như quan điểm về việc IsDefined rẻ hơn ... nhưng trong hầu hết các trường hợp (và cụ thể là các bài kiểm tra đơn vị), bạn khó có thể nhận thấy sự khác biệt. Có thể nếu đó là một vòng lặp chặt chẽ trong mã sản xuất ...
Marc Gravell

@ Marc- Tôi đồng ý rằng sự khác biệt về hiệu suất có thể sẽ không đáng chú ý trong một bài kiểm tra đơn vị. Tôi sẽ lấy thuộc tính nếu tôi cần sử dụng nó, như bạn nói là tình huống trong hầu hết các trường hợp. Gần đây tôi đã sử dụng IsDefined trong một khuôn khổ mà tôi đang viết để loại trừ một cột trong danh sách thả xuống của các trường có thể sắp xếp - điều này hoạt động tốt vì tôi không cần phải sử dụng đến chính thuộc tính.
RichardOD

Làm thế nào chúng ta có thể kiểm tra cùng một phương pháp?
Manvinder Singh

80

Giống như cách bạn thường kiểm tra một thuộc tính trên một lớp.

Đây là một số mã mẫu.

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

Tôi nghĩ rằng trong nhiều trường hợp, việc kiểm tra sự tồn tại của một thuộc tính trong bài kiểm tra đơn vị là sai. Vì tôi chưa sử dụng chức năng điều khiển phụ của người đóng góp MVC nên tôi không thể nhận xét liệu nó có phù hợp trong trường hợp này hay không.


Đã +1 và sau đó nhận thấy lỗi. Nó phải là .IsDefined (typeof (Type), false);
Alexander Beletsky

@alexanderb bạn tất nhiên đúng. Tôi đã cập nhật câu trả lời của mình bây giờ. Tôi không được kiểm tra câu trả lời của mình đối với trình biên dịch tại thời điểm đó! Cảm ơn vì đã chỉ ra lỗi
RichardOD

10
phương pháp này là nhanh hơn sau đó trước
Slava

18

Cũng có thể sử dụng generic về điều này:

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

Bằng cách này bạn không cần cái khác typeof(...), có thể làm cho mã sạch hơn.


Điều này không làm việc cho tôi. Tôi usingđang thiếu .. cái nào ?

@Scanzy Tôi không chắc, bạn không sử dụng IDE phải không? (Thông thường họ đề nghị đúng using) Bạn mắc lỗi gì?
Kroltan

1
ok, đây tôi thấy GetCustomAttribute<SomeAttribute>phương pháp là sẵn từ .NET 4.5 và IDE của tôi đã được thiết lập để 3,5 nên mọi thứ đều rõ ràng bây giờ

9

Tôi biết chủ đề này thực sự cũ, nhưng nếu ai đó tình cờ gặp nó, bạn có thể thấy dự án thông thạo rất thuận tiện để thực hiện loại xác nhận này.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.