@visibleForTestingとは?

はじめに

あるメソッドやWidgetをテストしたい時は、それらがtestフォルダから参照できるようにするためにpublicにする必要があります。

しかし、unitテストのためにメソッドをprivateからpublicに変更して外部から参照できるようにするのは、安全性が低くなってしまい微妙です。

また、Widgetをコンポーネントとして切り出すときは、基本的にprivateにしますが、これもテストのためにpublicにするのはあまり良い手段だとは言えません。

このような悩みを解決するのが@visibleForTestingです。

@visibleForTestingって?

公式ページでは以下のように記載されています。

Used to annotate a declaration that was made public, so that it is more visible than otherwise necessary, to make code testable.

Tools, such as the analyzer, can provide feedback if the annotation is associated with a declaration not in the lib folder of a package, or a private declaration, or a declaration in an unnamed static extension, or the declaration is referenced outside of its defining library or a library which is in the test folder of the defining package.

簡単に要約すると以下の通りです。

コードをtestableにするアノテーションやで💪

@visibleForTestingを付ければ、定義されたもの(関数やクラスなど)が定義ファイル、もしくはtestフォルダ外から参照された場合、analyzerがフィードバック(警告)出すぜ!って感じです。

つまり、このアノテーションをつけることで、テストのためにpublicにしたメソッドやWidgetが他ファイルから参照されるのを防ぐことができます。

これでtestのためにprivateからpublicに変更したコードが他ファイルから使われることを防げそうですね!

使用例

toMapメソッドをテストするためにpublicにした例を示します。

1
2
3
4
@visibleForTesting
Map<String, dynamic> toMap(String json) {
  return jsonDecode(json) as Map<String, dynamic>;
}

上記のコードでは、@visibleForTestingアノテーションを付けているので他ファイルから参照すると以下のような警告が出ます。

“visibleForTesting_warning”

警告は無視できるじゃないか

ここで一点問題があります。

そうです、警告は無視できちゃうんです。できればwarningではなくerrorを出すようにしてビルドできないようにしたいですね。

そんな時は、Dart analysisの機能を活用します。

analysis_options.yamlに以下を記述するだけです。

1
2
3
analyzer:
  errors:
    invalid_use_of_visible_for_testing_member: error

これで警告がコンパイルエラーに変わりました🎉

“visibleForTesting_error”

まとめ

@visibleForTestingアノテーションを使うことで不必要なコードの参照を検出できて便利。

また、Dart analysisの機能を活用することで、警告をコンパイルエラー変更することができて素晴らしい💪

参考

comments powered by Disqus