2012-06-11 34 views
7

私はScala(Javaから)には新しく、TDD/BDDを開発したいと思います。だからScalaについて多くを知る前に、私はすでにScalatestに飛び込んできました。スカラユニットテストのセットアップ(アクセス修飾子修飾子を使用しますか?)

私はあなたができるだけテストしたいという観点から、ユニットテストのための良いアクセス戦略だと思います。

私がテストしたいクラスワールドと、ワールドについてすべてを知ってはいけないクラスエージェントがあるとします。

package program { 
    package world { 
    class World { 
     private var notForAgent 
     def forAgentDuringActing 
     // forAgentDuringActing has an important side effect in notForAgent 
    } 
    } 

    package agent { 
    class Agent 
    // would call World.forAgentDuringActing 
    } 

    package world.test { 
    class WorldSpec extends FunSpec { 
     describe("The world") { 
     it("should have side-effect behaviour when the agent acts on it") { 
      // ... the test ... 
     } 
     } 
    } 
    } 
} 

これらのパッケージ宣言は私にとって神聖ではありません。 私が本当に欲しいのは、WorldSpecは、ワールドへのコンパニオンオブジェクトのようなものになるため、副作用をテストできることです。

おそらく、アクセス修飾子修飾子が役立つと思っていました。私はprivate[world] notForAgentと言うことができますが、それは本当に私が望むよりもアクセスが多いです。私が実際に望むのはprivate[this, test.WorldSpec] notForAgentのようなものですが、複数の修飾子を使用することはできません。

これをテスト可能にするにはどうすればよいですか?あるいは、あなたの思考がどこに間違った方向に向いているのかを示すことができますか?

p.s.私は、「私は決して秘密をテストしない」という声明を知っているしかし、私はまた、 "テストはコード自体よりも重要です。テストのためにアクセス修飾子を変更する必要がある場合は変更してください"という意見も知っています。しかし、私はこのスレッドで議論を避けたいと思います。

答えて

9

"私的メソッドをテストする方法"をお探しならば、ScalaTestはこれを実際にサポートしています。 hereを参照してください。

class C { 
    private def m(x: Int) = x 
} 

class CTests extends /*any test suite you like*/ with PrivateMethodTester { 
    val decoratedM = PrivateMethod[Int]('m) 
    val c = new C 
    val actual = c invokePrivate decoratedM(4711) 
    val expected = 4711 
    actual should be(expected) // this line depends on the test suite you've chosen 
} 
+0

はい、私はそれについて知っていました。しかし、私がテストしたい状態はvarであり、メソッドではありません。それでも、あなたの答えは実際には使えます。なぜならScalaもプライベートvalのゲッターメソッドを作るからです。だから、あなたはこのようにテストを行うことができます。 これをより自然な方法で許可する方法はありませんか(コンパニオンオブジェクトの場合など)。 – qkrijger

+0

私はまだ15の評判を持っていないので、私はあなたの答えを投票することができません... :( – qkrijger

+0

私はこのような方法でいくつかのテストを実装しているので、空気はビットコード臭になると言わなければなりません。 1つは、このテストはリファクタリングの後に壊れます(これは大きな問題ではありませんが、クリーンではありません)。私はセットアップを改善する方法についてアイデアを持っています。コンパニオンのような単体テストオブジェクトですが、(可能であれば)そのようなものを実現する方法はわかりません。 – qkrijger