クラスに属性があるかどうかをテストしますか?


101

私は少しテストファースト開発をしようとしています、そして私のクラスが属性でマークされていることを確認しようとしています:

[SubControllerActionToViewDataAttribute]
public class ScheduleController : Controller

クラスにその属性が割り当てられていることを単体テストするにはどうすればよいですか?

回答:


123

それを確認します

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

nullではない(Assert.IsNotNullまたは類似)

(ではなくこれを使用する理由IsDefinedは、ほとんどの場合、属性の一部のプロパティも検証したいということです...)


6
属性が存在するかどうかのみを確認するには、通常、パラメーターなし/プロパティなしの属性に必要なことですが、.IsDefinedを使用すると、メタデータにクエリを実行し、属性オブジェクトを逆シリアル化およびインスタンス化しないため、より安価です。
Lasse V. Karlsen、

1
IsDefinedの方が安くなっている点も同じですが、ほとんどの場合(特にユニットテスト)、違いに気付くことはほとんどありません。多分それが生産コードのタイトなループだったのなら...
マーク・グラベル

@ Marc-単体テストではパフォーマンスの違いはおそらく目立たないことに同意します。必要に応じて属性を取得します。これは、ほとんどの場合シナリオです。私は最近、IsDefinedを使用して、並べ替え可能なフィールドのドロップダウンから列を除外するために作成しているフレームワークで使用しました。これは、属性自体に使用する必要がないため、うまく機能しました。
RichardOD 08

メソッドに対して同じようにテストするにはどうすればよいですか?
Manvinder Singh

80

通常、クラスの属性をチェックするのと同じです。

ここにいくつかのサンプルコードがあります。

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

多くの場合、単体テストで属性の存在をテストすることは間違っていると思います。MVC contribのサブコントローラー機能を使用していないので、この場合でも適切かどうかはコメントできません。


+1した後、エラーに気づいた。.IsDefined(typeof(Type)、false);である必要があります。
Alexander Beletsky

@alexanderbあなたはもちろん正しいです。回答を更新しました。そのとき、コンパイラに対して私の答えをチェックしてはいけません!エラーを指摘してくれてありがとう
RichardOD

10
このアプローチは以前よりも高速です
スラバ2014

18

これにジェネリックを使用することも可能です:

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

この方法typeof(...)では、コードをよりクリーンにすることができる別のは必要ありません。


これは私にはうまくいきません。どれusingが欠けていますか?

@Scanzyわからない、IDEを使っていませんか?(通常、彼らは正しいことを示唆していますusing)どのエラーが発生しますか?
Kroltan 2017

1
わかりました、ここで私はGetCustomAttribute<SomeAttribute>メソッドが.NET 4.5から利用可能であり、IDEが3.5に設定されているため、すべてが明確になりました

9

私はこのスレッドが本当に古いことを知っていますが、誰かがそれに出くわした場合、fluentassertionsプロジェクトがこの種のアサーションを行うのに非常に便利であると感じるかもしれません。

typeof(MyPresentationModel).Should().BeDecoratedWith<SomeAttribute>();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.