ObjcUnit その5

2003/06/17


undoにだまされるな!

前回、前々回と説明の都合で思いっきり嘘を書いてあります(^^;
あれ?と思ったことはありませんでしたか? もし思わなかったとしたら、Objective-CもTest Firstも理解できていないことになりますので、勉強しなおしてください(_ _)


テストをちゃんと先に書こう その1

  1. テストしてない!
    面倒なので最初から種明かしをしちゃいましょう。やっちゃいけなかったのは、この部分です。
    - (BOOL) isEqual: (id)another
    {
    	if (value == [another intValue]) {
    		return TRUE;
    	} else {
    		return FALSE;
    	}
    }
    
    何がいけないかというと、メソッドintValueはテストしてないということです。
    C++だったらprivateメンバに直接アクセスするようなところでも、Objective-Cではメソッドを定義しなくてはなりません。メソッドを定義すれば、どこからでもアクセスできるようになります。したがって、実装する前に先にテストを書かなければなりません
  2. To Do List
    というわけで、メソッドintValueを実装する前には、こんなテストを書いておく必要があるわけです。
    - (void) testIntValue
    {
    	SmallInteger* one = [SmallInteger initWithInt:1];
    	SmallInteger* two = [SmallInteger initWithInt:2];
    	
    	[self assertTrue:(1 == [one intValue])];
    	[self assertTrue:(2 == [two intValue])];
    }
    
    でも、こんなことをやっている間にメソッドisEqual:の実装を忘れては困ります。だって、メソッドisEqual:を実装するためにやっているわけですから。そこで、今、何をやるべきか、何のために今やっているのかを分かるようにTo Do Listにしておくわけです。
  3. intValueを実装しよう!
    まずはテストtestIntValueを成功させるように、メソッドintValueを実装するわけです。
    - (int) intValue
    {
    	return value;
    }
    
    で、これが済むと、To Do Listから「intValue実装」がなくなります。
  4. isEqual:をやっと実装できる
    というわけで、メソッドisEqual:をやっと実装できるようになったわけです。もし、2つも3つもテストが失敗してたら、何を直しているんだか分からなくなってしまうでしょ? ほらほらそういうときこそ、Fake Itを使うんですよ。

ここで「終わった」と思ってしまっては、またundoにだまされちゃいますよ。ほら、もう1つテストしてないでしょ?


今日のおまけ

Objective-Cには、private methodはありません。ヘッダで宣言しなくてもメソッドを定義できます。こうすると、表向きメソッドを見えないようにすることはできます。でも、動的にメソッドをサーチすれば呼び出せちゃいます。したがって、C++だったら、privateメンバにアクセスするくらいでテストするわけないのに、Objective-Cではテストが必要になってくるわけです。

もちろん、private methodであることにしてテストしないという選択もありでしょう。


戻る