2009-08-04 18 views
75

Ich versuche, ein wenig Test-First-Entwicklung zu tun, und ich versuche, dass meine Klassen mit einem Attribut gekennzeichnet sind, um zu überprüfen:Testen, ob eine Klasse ein Attribut hat?

[SubControllerActionToViewDataAttribute] 
public class ScheduleController : Controller 

Wie Unit-Test muss ich, dass die Klasse dieses Attribut hat zugewiesen dazu?

Antwort

97

prüfen, ob

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

nicht null ist (Assert.IsNotNull oder ähnlich)

(der Grund, warum ich diese verwenden, anstatt IsDefined ist, dass die meisten Male, die ich möchte auch einige Eigenschaften des Attributs zu validieren. ...)

+5

nur zu überprüfen, ob das Attribut vorhanden ist, das ist in der Regel alles, was für parameterlose/eigenschaftslose Attribute benötigt wird, ist es billiger zu verwenden .IsDefined, da es die Metadaten abfragen wird, und das Attributobjekt nicht deserialisiert und instanziiert. –

+0

Wie ist der Punkt über IsDefined ist billiger ... aber in den meisten Fällen (und insbesondere Unit-Tests) ist es unwahrscheinlich, dass Sie den Unterschied bemerken. Vielleicht, wenn es eine enge Schleife im Produktionscode war ... –

+0

@ Marc - Ich stimme zu, dass der Unterschied in der Leistung wahrscheinlich nicht in einem Komponententest auffallen würde. Ich würde das Attribut bekommen, wenn ich es benutzen müsste, was in den meisten Fällen das Szenario ist. Ich habe kürzlich IsDefined in einem Framework verwendet, das ich geschrieben habe, um eine Spalte in einem Dropdown-Feld mit sortierbaren Feldern auszuschließen. Dies funktionierte gut, da ich das Attribut nicht selbst verwenden musste. – RichardOD

54

Dasselbe, das Sie normalerweise nach einem Attribut für eine Klasse überprüfen würden.

Hier ist ein Beispielcode.

Ich denke in vielen Fällen ist das Testen auf die Existenz eines Attributs in einem Komponententest falsch. Da ich die Subcontroller-Funktionalität von MVC contrib nicht verwendet habe, kann ich nicht sagen, ob dies in diesem Fall angemessen ist.

+0

Hat +1 und dann Fehler festgestellt. Es sollte .IsDefined sein (typeof (Type), false); –

+0

@alexanderb hast du natürlich recht. Ich habe meine Antwort jetzt aktualisiert. Ich muss meine Antwort gegen den Compiler zu diesem Zeitpunkt nicht überprüfen! Danke für den Hinweis auf den Fehler – RichardOD

+7

dieser Ansatz ist schneller als vorherige – Slava

5

Ich weiß, dass dieser Thread wirklich alt ist, aber wenn jemand darauf stolpert finden Sie fluentassertions Projekt sehr bequem für diese Art von Behauptungen.

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>(); 
8

Es ist auch möglich, Generika dazu zu verwenden:

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

Auf diese Weise brauchen Sie nicht eine andere typeof(...), die den Code sauberer machen.

+0

Dies funktioniert nicht für mich. Welches 'using' .. vermisse ich? –

+0

@Scanzy Ich bin mir nicht sicher, verwenden Sie nicht eine IDE? (In der Regel schlagen sie das richtige 'using' vor) Welchen Fehler bekommen Sie? – Kroltan

+1

ok, [hier] (https://msdn.microsoft.com/it-it/library/hh194292 (v = vs.110) .aspx) Ich fand die 'GetCustomAttribute ' Methode ist verfügbar von .NET 4.5 und meine IDE wurde auf 3,5 eingestellt, alles ist jetzt klar –

Verwandte Themen