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?

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 ....)


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.


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.


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>();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.