Teste se uma classe possui um atributo?


101

Estou tentando fazer um pequeno desenvolvimento Test-First, e estou tentando verificar se minhas classes estão marcadas com um atributo:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Como faço um teste de unidade para verificar se a classe tem esse atributo atribuído a ela?

Respostas:


123

verifique isso

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

não é nulo ( Assert.IsNotNullou semelhante)

(a razão pela qual eu uso isso IsDefinedé que na maioria das vezes também quero validar algumas propriedades do atributo ...)


6
para verificar apenas se o atributo está presente, que normalmente é tudo o que é necessário para atributos sem parâmetros / propriedades, é mais barato usar .IsDefined, pois irá consultar os metadados, e não desserializar e instanciar o objeto de atributo.
Lasse V. Karlsen

1
Como é o ponto sobre IsDefined ser mais barato ... mas na maioria dos casos (e em testes de unidade específicos) é improvável que você note a diferença. Talvez se fosse um loop apertado no código de produção ...
Marc Gravell

@ Marc- Eu concordo que a diferença no desempenho provavelmente não seria perceptível em um teste de unidade. Eu obteria o atributo se precisasse usá-lo, o que, como você diz, é o cenário na maioria dos casos. Recentemente, usei IsDefined em uma estrutura que estava escrevendo para excluir uma coluna em uma lista suspensa de campos classificáveis ​​- isso funcionou bem, pois não precisei usar o atributo em si.
RichardOD

Como podemos testar o mesmo para um método?
Manvinder Singh

80

O mesmo que você normalmente verificaria para um atributo em uma classe.

Aqui está um exemplo de código.

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

Eu acho que em muitos casos, testar a existência de um atributo em um teste de unidade está errado. Como eu não usei a funcionalidade do subcontrolador do MVC contrib, não posso comentar se é apropriado neste caso.


Fiz +1 e percebi um erro. Deve ser .IsDefined (typeof (Type), false);
Alexander Beletsky,

@alexanderb, é claro que você está certo. Eu atualizei minha resposta agora. Não devo conferir minha resposta com o compilador na época! Obrigado por apontar o erro
RichardOD

10
esta abordagem é mais rápida que a anterior
Slava

18

Também é possível usar genéricos neste:

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

Dessa forma, você não precisa de outro typeof(...), o que pode tornar o código mais limpo.


Isso não funciona para mim. Qual using.. estou perdendo?

@Scanzy Não tenho certeza, você não está usando um IDE? (Normalmente eles sugerem o correto using) Que erro você obtém?
Kroltan de

1
ok, aqui eu descobri que o GetCustomAttribute<SomeAttribute>método está disponível no .NET 4.5 e meu IDE foi configurado para 3,5, então tudo está claro agora

9

Eu sei que este tópico é muito antigo, mas se alguém topar com ele, você pode achar o projeto fluentassertions muito conveniente para fazer este tipo de asserções.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.