Testen, ob eine Klasse ein Attribut hat?

100

Ich versuche, eine kleine Test-First-Entwicklung durchzuführen, und ich versuche zu überprüfen, ob meine Klassen mit einem Attribut gekennzeichnet sind:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

Wie teste ich, ob der Klasse dieses Attribut zugewiesen ist?

JoshRivers
quelle

Antworten:

122

prüfe das

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

ist nicht null ( Assert.IsNotNulloder ähnlich)

(Der Grund, warum ich dies verwende, IsDefinedist, dass ich meistens auch einige Eigenschaften des Attributs überprüfen möchte ....)

Marc Gravell
quelle
6
Um nur zu überprüfen, ob das Attribut vorhanden ist, was normalerweise alles ist, was für parameterlose / eigentumslose Attribute benötigt wird, ist es billiger, .IsDefined zu verwenden, da es die Metadaten abfragt und das Attributobjekt nicht deserialisiert und instanziiert.
Lasse V. Karlsen
1
Wie der Punkt ist, an dem IsDefined billiger ist ... aber in den meisten Fällen (und insbesondere bei Unit-Tests) ist es unwahrscheinlich, dass Sie den Unterschied bemerken. Vielleicht, wenn es eine enge Schleife im Produktionscode war ...
Marc Gravell
@ Marc- Ich stimme zu, dass der Leistungsunterschied bei einem Unit-Test wahrscheinlich nicht spürbar wäre. Ich würde das Attribut erhalten, wenn ich es verwenden müsste, was, wie Sie sagen, in den meisten Fällen das Szenario ist. Ich habe IsDefined kürzlich in einem Framework verwendet, das ich geschrieben habe, um eine Spalte in einer Dropdown-Liste sortierbarer Felder auszuschließen. Dies hat gut funktioniert, da ich das Attribut selbst nicht verwenden musste.
RichardOD
Wie können wir dasselbe für eine Methode testen?
Manvinder Singh
80

Das gleiche, das Sie normalerweise für ein Attribut in einer Klasse suchen würden.

Hier ist ein Beispielcode.

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

Ich denke in vielen Fällen ist es falsch, in einem Komponententest auf das Vorhandensein eines Attributs zu testen. Da ich die Subcontroller-Funktionalität von MVC Contrib nicht verwendet habe, kann ich nicht beurteilen, ob dies in diesem Fall angemessen ist.

RichardOD
quelle
Habe +1 und dann Fehler bemerkt. Es sollte .IsDefined sein (typeof (Type), false);
Alexander Beletsky
@alexanderb du hast natürlich recht. Ich habe meine Antwort jetzt aktualisiert. Ich darf meine Antwort zu diesem Zeitpunkt nicht mit dem Compiler vergleichen! Vielen Dank für den Hinweis auf den Fehler
RichardOD
10
Dieser Ansatz ist schneller als zuvor
Slava
18

Es ist auch möglich, Generika zu verwenden:

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

Auf diese Weise benötigen Sie keine weitere typeof(...), wodurch der Code sauberer wird.

Kroltan
quelle
Das funktioniert bei mir nicht. Welches using.. vermisse ich?
@ Scanzy Ich bin nicht sicher, verwenden Sie keine IDE? (Normalerweise schlagen sie das Richtige vor. using) Welchen Fehler erhalten Sie?
Kroltan
1
ok, hier habe ich festgestellt, dass die GetCustomAttribute<SomeAttribute>Methode von .NET 4.5
9

Ich weiß, dass dieser Thread wirklich alt ist, aber wenn jemand darauf stößt, kann es sein, dass das Projekt für fließende Behauptungen sehr praktisch ist, um diese Art von Behauptungen aufzustellen .

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