Проверить, есть ли у класса атрибут?

102

Я пытаюсь выполнить небольшую разработку Test-First, и я пытаюсь проверить, что мои классы отмечены атрибутом:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Как я могу модульно проверить, что классу назначен этот атрибут?

ДжошРиверс
источник

Ответы:

124

Проверь это

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

не является нулевым ( Assert.IsNotNullили аналогичным)

(Причина, по которой я использую это, а не в IsDefinedтом, что в большинстве случаев я хочу также проверить некоторые свойства атрибута ....)

Марк Гравелл
источник
6
только для проверки наличия атрибута, что обычно является всем, что необходимо для атрибутов без параметров / без свойств, дешевле использовать .IsDefined, поскольку он будет запрашивать метаданные, а не десериализовать и создать экземпляр объекта атрибута.
Лассе В. Карлсен,
1
Дело в том, что IsDefined дешевле ... но в большинстве случаев (и в частности в модульных тестах) вы вряд ли заметите разницу. Может быть, если бы это был жесткий цикл в производственном коде ...
Марк Грейвелл
@ Marc - Я согласен с тем, что разница в производительности, вероятно, не будет заметна в модульном тесте. Я бы получил атрибут, если бы мне нужно было его использовать, что, как вы говорите, является сценарием в большинстве случаев. Недавно я использовал IsDefined во фреймворке, который писал, чтобы исключить столбец из раскрывающегося списка сортируемых полей - это сработало хорошо, так как мне не нужно было использовать сам атрибут.
RichardOD
Как мы можем проверить то же самое для метода?
Манвиндер Сингх,
81

То же самое, что вы обычно проверяете для атрибута в классе.

Вот пример кода.

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

Я думаю, что во многих случаях проверка наличия атрибута в модульном тесте неверна. Поскольку я не использовал функциональные возможности субконтроллера MVC contrib, я не могу прокомментировать, подходит ли это в данном случае.

RichardOD
источник
Сделал +1, а потом заметил ошибку. Это должно быть .IsDefined (typeof (Type), false);
Александр Белецкий
@alexanderb вы конечно правы. Я обновил свой ответ сейчас. Я не должен проверять свой ответ компилятором в то время! Спасибо за указание на ошибку
RichardOD
10
этот подход быстрее, чем предыдущий
Слава
18

Здесь также можно использовать дженерики:

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

Таким образом, вам не понадобится другой typeof(...), который может сделать код чище.

Кролтан
источник
У меня это не работает. Что using.. я скучаю?
@Scanzy Я не уверен, вы не используете IDE? (Обычно они подсказывают правильное using) Какую ошибку вы получаете?
Kroltan
1
хорошо, здесь я обнаружил, что GetCustomAttribute<SomeAttribute>метод доступен из .NET 4.5, и моя IDE была установлена ​​на 3.5, так что теперь все ясно
9

Я знаю, что эта ветка действительно устарела , но если кто-нибудь наткнется на нее, вы можете найти проект fluentassertions очень удобным для выполнения такого рода утверждений.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
Алексей Л.
источник