大村です。
Kaoru Hosokawa <khosokawa@....com> wrote:
from "[XP-jp:00923] Re: テストのためだけのメソッド"
>私は、この様に考えてみました。
>
>---
>「テストのためだけのメソッド」の定義
>
>そのメソッドを削除しても、コンパイルエラーが出るのはテストからだけであれば、
>そのメソッドは、「テストのためだけのメソッド」である。
>---
>
>この定義からすると、save() は、テストのためだけのメソッドになります。それか
>ら、setName() も同じです。現時点では、テストのみで使用されていますから。
>
>--
気持ちはよく分ります。
定義としてちょっと分らないのは、ここでコンパイルする対象となるクラスにはどういうものを
考えていらっしゃいますか。
テスト対象のクラスを使用するすべてのクライアント・クラスなのかなと思うのですが、
どんなもんでしょう。
◇
テストのためだけのメソッドということで、私が最初に考えていたものは、
テスト対象のクラスでしか実装することのできないようなメソッドであって
設計上、そのメソッドはpublic/protectedなインターフェイスとして不要であるもの
なのかなと思っていました。
save()については、別のメールでも書きましたが、そもそもテスト対象クラスのsave()を
関係のないテストで使うべきでないと思うので、ホソカワさんのヘルパクラス(このメール
[XPJ-00917]前回は見落していました)のような方法を取るべきだと思っています。
そう考えると、議論すべきだと私の思っているテストのためだけのメソッドというのは
もっと限定されたものになるのです。
テストというのは、対象のオブジェクトがある条件を満たす初期状態のとき、
一連のメソッドを実行した後での状態が、期待したものであるかどうかをチェックする
ということだと思います。
だから、対象クラスでテストのためだけのメソッドを作るとすると
(1) public/protectedなメソッドだけでは認知できないオブジェクトの状態を知るためのメソッド
(2) public/protectedなメソッドだけでは設定できないオブジェクトの状態を作り出すためのメソッド
くらいしか思い付きませんでした。
前者は、
(1a) 対象クラスの設計者が、意図的にそのメソッドをアクセス不能とする場合や、
(1b) publicなメソッドで認知されるそのクラスのモデル(*1)のようなものと、実装のモデルとが
異なっていて、実装のほうは見せないようにする場合
などがあると思います。
(*1 これはクラスのメンタル・モデルと読んでもいいのかなと思っています。だとすると、機能仕様と
いうのはシステムのメンタル・モデルの記述ということになる..余談)
後者は、
(2a) publicなメソッドを使えば、なんとか状態を作れるけれど、面倒くさいので一気にやるメソッドがほしい場合とか
(2b) そもそもそういう状態は作れない場合とか
があるのかなと思います。
(ここ、かなりいいかげんなので、間違い、指摘していただけるとありがたいと思います)
そういうことを考えていたので、最終兵器、reflectionを使えば、そういうメソッドを作る必要はないなということも書きました。
で、細かいことをいい始めると長くなるのではしょってしまつて、一番、問題になると思ったのは、
インターフェイスのモデルと実装のモデルが違うときに、何をテストすればいいのかなということです。
実装のテストを直接しようとすると、インターフェイスとはずれた内部状態を見る必要がでてきて、
そのためのメソッドを作らなくてはならなくなりますが、そのメソッドは設計上の本来のインターフェイス
を壊すので、いやですよね。
で、
・ XPでは、そんなねじれた設計はしないのではないかと思いますがどうでしょう。
・ もし、そういうことをした場合、たとえば、こんなふうにしてテストする。
つまり、実装のクラスを別途作成し、対象のクラスだったものは、実装のクラスからそのインターフェイスへの
変換だけを行うものとする。こうすることで、実装のクラスののテストの後、実装のクラスからインターフェイスの
クラスへの変換のテストを行えば、中身を見なくてもなんとかなる...ちょっと大変なのは、そもそも設計が
ねじれているからなので、仕方がないと考える。
こういう問題意識自体が、ずれているのかなあとも思えてきたんで、議論の行末をみていたいと
思います。