テストを書き直して醜いテストを修正することはできません。テスト中の API を再設計することによってのみ修正できます。
まあ、技術的には、あなたが本当に一生懸命努力したり、非常に邪悪で、非常に愚かで、非常に酔ったり、非常に疲れていたりすると、優れた API の醜いテストを書くことが可能です。しかし、醜いテストを書くには努力が必要で、プログラマーは怠け者です。醜いテストを書くことはほとんど不可能です: 何かを突き刺し、何かを取り出し、期待した結果が得られたかどうかをチェックします。それでおしまい。そこには醜いものは何もありません。
テストでは、API のユーザーが使用するのと同じ方法で API を使用するだけです。これは基本的に、API を適切に使用する方法の例であり、ほとんど副作用として、API が実際に適切に実装されていることを確認します。そのため、醜いテストは悪い API 設計の良い指標であり、TDD を行わなくても API 設計をテストすることは良いことでもあります。
この特定のケースでは、API を改善するためのかなりの方法を見ることができますが、これらの提案は必然的に不完全で、浅く、単純化されています (言うまでもなく、間違っている可能性もあります)。私はあなたのドメインについて何も知らないからです。
- Better Names :
setRoot
ルートを設定しているように聞こえます。ただし、false
が階層のルートでない限り、実際に設定しているのは、このタグがルートであるかどうかであると思います。したがって、それはむしろisRoot
またはmakeRoot
またはsetIsRoot
またはそのような名前にする必要があります。
- より良いデフォルト: に進み
setRoot
ます。私の推測が正しいと仮定すると、タグがルートであるかどうかが設定されます。デフォルトは間違った方法です。「ルート」の概念の定義そのものにより、ルートは1 つしか存在できません。そのため、ユーザーが実際にルートを定義している1回を除いて、setRoot(false)
毎回を指定するようにユーザーに強制しています。非ルート タグがデフォルトである必要があり、実際にルートであるその 1 つのタグに対してのみ強制される必要があります。setRoot(true)
- より良いデフォルト、パート II :
setRole(null)
. 真剣に?ユーザーに役割を明示的に設定解除するよう強制していますか? 単純に unset をデフォルトにしないのはなぜですか? 結局のところ、テストは「ロールもルートも定義されていない場合」と呼ばれるのに、なぜそれらを定義するのでしょうか。
- Fluent API / Builder パターン:本当に無効なオブジェクトを作成する必要がある場合 (次のポイントを参照)、少なくとも Fluent API や Builder パターンなどを使用してください。
- Only Construct Valid Objects : しかし実際には、オブジェクトは構築時に常に有効で、完全で、完全に構成されている必要があります。オブジェクトを構築してから構成する必要はありません。
そうすれば、テストは基本的に次のようになります。
package com.xyz
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import com.xyz.SecurityService
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.mockito.Matchers._
import javax.servlet.jsp.tagext.Tag
class CheckRoleTagSpec extends FlatSpec with ShouldMatchers with MockitoSugar {
behavior of "CheckRole tag"
it should "allow access when neither role nor root defined" in {
val tag = new CheckRoleTag(mock[SecurityService], "group", "portal")
tag.doStartTag should be(Tag.SKIP_BODY)
}
}