懸田さん,こんにちは.石井です.
紹介していただいた記事はまだ読んでないのですが,最近この話題には興味が
ありまして.
> この記事にある「Mockフレンドリーにリファクタリング」するか「Aspectによる
> Mockを適用」するかの境界が実際にきちんと引けるかが自信ないですが(^^;
> このテクニックは覚えておいて損はないですね。
AspectJ を少し使ってみたのですが,実装コードのフックはコンパイル時に決
まってしまうため,MockObject と比べて使いにくいということもあると思い
ます.
つまり,実装クラス Foo のテストについて,テストメソッド testA では
MockFooA クラスという MockObject, テストメソッド testB では MockFooB
クラスという MockObject がほしい場合,AspectJ では対応できないのでは
ないかと.AspectJ では,すでにフックされている Foo クラスが実体として
あるわけですから.
ユニットテストの実行中,ずっと共通のフックをしたい場合には AspectJ は
使えそうです.例えば,メール送信を行う箇所にフックして,テスト時には実
際にメール送信を行わず,メール内容をファイルに書き出すようにしておくと.
それで,テストケースは書き出されたファイルの内容を見てテストを行う,と
か(実際のメール送信については,受け入れテストで行うようにする).
> AspectとUnitTestの絡みはDbCも含めてまだまだ面白そうです。
Aspect と JUnit について,まず思いついた応用が次のようなことでした.
- TestCase に対して,setUp と tearDown メソッドを横断的に定義できたら
便利じゃないかな.
- テスト全体のカバレッジツールとして使えないかな(偶然[XP-jp:03592]に
も出てますが)
で,最初の setUp と tearDown の代わりになるか実験してみたのですが,
AspectJ が吐くフックメソッドって
[フックされるメソッド名]$acjXXXXX
という風になるんですね.だから testYYY だと フックメソッドが
testYYY$ajcXXXX になって,JUnitがリフレクションでテストメソッドと勘違
いしてダメじゃん,ということになりました.
(ただ,回避する方法はあって static Test TestCase.suite() メソッドを
around して $acj という名前を含むメソッドを取り除けばOK).
次のテストカバレッジツールとして代用できるかという問題は,まだ着手して
いませんが,できるんではないかと思います.AspectJ は,メソッドが呼ばれ
たか? という調査は簡単にできそうなのですが,メソッドが呼ばれてないか?
という調査はちょっと面倒くさそうです.
将来,AspectJ はバイトコードにも対応という話があるので,夢が広がります
ね.今でもデコンパイラ使って頑張ればできるのかもしれませんが.
というわけで,ひさびさの発言でした.
では.