矢崎です。続きです。
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つ
だけのテストメソッドを実行し、終了するという具合です。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
で、ご質問に戻りますと、例えば、"testXXX"という名前がついた
インスタンスのsetUP()で例外が発生した場合、それがthrows節で
捕まえられた場合には、先述したとおり、TestResultクラスのイ
ンスタンスが拾ってくれます。そしてそのインスタンスの処理は
そこでおしまいです。testXXX()は実行されません。しかし、別の
インスタンスの実行までをとめることはしません。よって、
"testYYY"、"testZZZ"インスタンスの実行は行われます。
#もっとも、例の場合は全て同じsetUP()を使いますから、いずれの
場合もsetUP()で例外が発生してしまうでしょうけど、、、
#私の例ではふれていませんが、JUnitでは、TestCaseの異なるサブ
クラス(のインスタンス)をいっしょに実行できます。この場合、
setUp()で例外が発生するものもあれば、そうならないものも混在
することがあるわけです。
#補足ですが、
私の例では、setUpはテストをターゲットするクラスのインスタンス
を生成しているだけですが、もちろんテストの内容によっては、それ
以外の処理も行わなければなりません。System.out.printlnなんか
やってもかまいません。
残りはまた後で、、、
--
矢崎博英 firo@....jp