Verificare se una classe ha un attributo?


101

Sto provando a fare un po 'di sviluppo Test-First e sto cercando di verificare che le mie classi siano contrassegnate con un attributo:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Come faccio a testare l'unità che la classe abbia quell'attributo assegnato?

Risposte:


123

controllalo

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

non è nullo ( Assert.IsNotNullo simile)

(il motivo per cui lo uso piuttosto che IsDefinedè che la maggior parte delle volte voglio convalidare anche alcune proprietà dell'attributo ....)


6
per controllare solo se l'attributo è presente, che di solito è tutto ciò che è necessario per attributi senza parametri / senza proprietà, è più economico usare .IsDefined, poiché interrogherà i metadati e non deserializzerà e istanzerà l'oggetto dell'attributo.
Lasse V. Karlsen

1
Come il punto sul fatto che IsDefined è più economico ... ma nella maggior parte dei casi (e in particolare nei test unitari) è improbabile che tu noti la differenza. Forse se fosse un anello stretto nel codice di produzione ...
Marc Gravell

@ Marc- Sono d'accordo sul fatto che la differenza di prestazioni probabilmente non sarebbe evidente in uno unit test. Otterrei l'attributo se avessi bisogno di usarlo, che come dici tu è lo scenario nella maggior parte dei casi. Recentemente ho utilizzato IsDefined in un framework che stavo scrivendo per escludere una colonna in un menu a discesa di campi ordinabili: ha funzionato bene poiché non avevo bisogno di usare l'attributo stesso.
RichardOD

Come possiamo testare lo stesso per un metodo?
Manvinder Singh,

80

Lo stesso che normalmente verificheresti per un attributo in una classe.

Ecco alcuni esempi di codice.

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

Penso che in molti casi testare l'esistenza di un attributo in uno unit test sia sbagliato. Dato che non ho utilizzato la funzionalità del controller secondario di MVC contrib, non posso commentare se sia appropriato in questo caso.


Ha fatto +1 e poi ha notato un errore. Dovrebbe essere .IsDefined (typeof (Type), false);
Alexander Beletsky

@alexanderb hai ovviamente ragione. Ho aggiornato la mia risposta ora. Al momento non devo controllare la mia risposta con il compilatore! Grazie per aver segnalato l'errore
RichardOD

10
questo approccio è più veloce del precedente
Slava

18

È anche possibile utilizzare i generici su questo:

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

In questo modo non è necessario un altro typeof(...), che può rendere il codice più pulito.


Questo non funziona per me. Quale using.. mi manca?

@Scanzy Non sono sicuro, non stai usando un IDE? (Di solito suggeriscono il corretto using) Che errore ricevi?
Kroltan

1
ok, qui ho scoperto che il GetCustomAttribute<SomeAttribute>metodo è disponibile da .NET 4.5 e il mio IDE era impostato su 3.5, quindi ora è tutto chiaro

9

So che questo thread è molto vecchio, ma se qualcuno ci si imbatte in esso, potresti trovare il progetto fluentassertions molto conveniente per fare questo tipo di affermazioni.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.