ホソカワです。
矢崎さん、ていねいな解答本当にありがとうございます。
on 2000/04/26 7:06 PM, firo at firo@....jp wrote:
> 矢崎です。続きです。
>
> firo wrote:
>
>>
>>>
>>>
>>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>> 3.必要ならばsetUpメソッドをオーバライドする。原則的に
>>>> はオーバライドすることになるでしょう。何をするかというと、
>>>> ユニットテストをする対象のオブジェクトをnewする。
>>>> newしたオブジェクトを入れておくためのインスタンス変数
>>>> も定義する。
>>>>
>>>> import junit.framework.*;
>>>>
>>>> public class ConcreteTestCase extends TestCase{
>>>>
>>>> /*以下の変数は任意。型はテストしたいクラス。数も自由*/
>>>> TestTarget aTestTarget; //3
>>>>
>>>> public ConcreteTestCase(String name){
>>>> super(name);
>>>> }
>>>>
>>>> /*setUpはリターンはvoid。引数はなしじゃないとだめ。*/
>>>> public void setUp(){ //3
>>>> aTestTarget = new TestTarget(); //3
>>>> } //3
>>>>
>>>> }
>>>>
>>>
>>> 例えば、setUp()でファイルをオープンしようとして、エラーになった場合、例外で
>>> 戻るのでしょうか?どこへ戻るのでしょうか?
>>
>
> setUp()と、tearDown()は、TestCaseクラスに空の
> メソッドとしてあって、以下のようになっています。
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> protected void setUp() throws Exception {
> }
>
> protected void tearDown() throws Exception {
> }
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ポイントは、throws節です。
>
> ConcreteTestCaseは、ご承知のとおりTestCaseのサブクラス
> で、setUp()とtearDown()をオーバライドします。
> したがって、もしsetUp()やtearDown()で例外が発生する可能
> 性がある場合、以下の2通りのいずれかのやり方で対処しなけ
> ればなりません。
>
> 1.オーバライドするsetUp()やtearDown()に、Exception又は
> Exceptionのサブクラスを伴うthrows節を宣言する。
> ex.
> public void setUp() throws IOException{
> aTestTarget = new TestTarget();
> }
>
> 2.setUp()やtearDown()の中で、try-catch節を使う。
> ex.
> public void setUp(){
> try{
> aTestTarget = new TestTarget();
> }catch(Throwable e){
> .......
> }
> }
>
> 1の方法をとった場合、throwされたExceptionは、どうなるか
> というと、TestResultクラスのインスタンスが拾ってくれます。
> よって、複数のテストをする場合でも、途中で終わったりせず、
> 最後まで実行されます。しかし、この途中で、とか最後まで、
> とかいうことを正確に説明するのがちょっと難しいので、ご質問
> から少しはずれて、JUnitの動きそのものを少しだけ、以下に説明
> します。
>
例外が発生する箇所は、自分で処理するということですね。
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 私の書いた例の場合、JUnitを実行すると、ConcreteTestCaseの
> インスタンスが、テストメソッドの数だけnewされます。それぞれ
> のインスタンスは、名前を持ちます。それは、テストメソッドの
> 名前になります。例でいえば、"testXXX"という名前を持つ、
> ConcreteTestCaseのインスタンス、"testYYY"という名前を持つ
> ConcreteTestCaseのインスタンス、"testZZZ"という名前を持つ
> ConcreteTestCaseのインスタンスの計3インスタンスが生成され
> るわけです。
>
> そしてJUnitは、上のインスタンス1つ1つを順に実行します。
> それぞれのインスタンスは、自分と同じ名前のテストメソッドだけ
> を実行します。
>
> つまり、、、
>
> "testXXX"という名前を持つインスタンスが実行されたときには、
> setUP(),testXXX(),tearDown()が実行されます。
> "testYYY"という名前を持つインスタンスが実行されたときには、
> setUP(),testYYY(),tearDown()が実行されます。
> "testZZZ"という名前を持つインスタンスが実行されたときには、
> setUP(),testZZZ(),tearDown()が実行されます。
>
> 各インスタンスは独立していて、何ら連携して動作しません。
> setUP()とtearDown()は、ロジックは同じものを使いますが、
> そこで生成されるオブジェクトは、インスタンスとしてはまった
> く別ものです。生成の仕方だけを等しくしているだけです。
>
> 例でいえば、
> public void setUp(){
> aTestTarget = new TestTarget();
> }
>
> となっていますが、各ConcreteTestCaseのインスタンスは、それ
> ぞれ、他の2つとはまったく独立にsetUP()を行い、別々のインス
> タンスを生成し、そのインスタンスに対して、まったく独立に1つ
> だけのテストメソッドを実行し、終了するという具合です。
>
これは、おもしろい!!
私は、setUp() は、一回実行されるだけかなと思っていました。と言う事は、一つ前
のテストがオブジェクトの状態を壊してしまう事を考えずに test メソッドを書いて
いいということですね。
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> で、ご質問に戻りますと、例えば、"testXXX"という名前がついた
> インスタンスのsetUP()で例外が発生した場合、それがthrows節で
> 捕まえられた場合には、先述したとおり、TestResultクラスのイ
> ンスタンスが拾ってくれます。そしてそのインスタンスの処理は
> そこでおしまいです。testXXX()は実行されません。しかし、別の
> インスタンスの実行までをとめることはしません。よって、
> "testYYY"、"testZZZ"インスタンスの実行は行われます。
>
> #もっとも、例の場合は全て同じsetUP()を使いますから、いずれの
> 場合もsetUP()で例外が発生してしまうでしょうけど、、、
>
> #私の例ではふれていませんが、JUnitでは、TestCaseの異なるサブ
> クラス(のインスタンス)をいっしょに実行できます。この場合、
> setUp()で例外が発生するものもあれば、そうならないものも混在
> することがあるわけです。
>
> #補足ですが、
> 私の例では、setUpはテストをターゲットするクラスのインスタンス
> を生成しているだけですが、もちろんテストの内容によっては、それ
> 以外の処理も行わなければなりません。System.out.printlnなんか
> やってもかまいません。
>
> 残りはまた後で、、、
説明ありがとうございました。
--
Kaoru Hosokawa
khosokawa@....com