矢崎です。ホソカワさんのアドバイスを受けて
太郎さんになって、ConfigTestをリファクタリング
します。ConfigTest.javaの現在最終バージョンは
[XP-jp:00884]です。
Kaoru Hosokawa さんwrote:
>
> testConstructor1 は、ちょっと長いと思いましたので refactor させていただきま
> した。
>
> public void testCorrectConfig() {
> String correctFilename = "CorrectConfig";
>
> createCorrectConfigFile(correctFileName);
> Config aConfig = new Config(correctFileName);
> assertEquals("test1", "extremeprogramming-jp", aConfig.getName());
> // ...
> }
>
> private void createCorrectConfigFile(String filename) {
> FileOutputStream fo;
> try {
> fo = new FileOutputStream(filename);
> } catch (FileNotFoundException e) {
> throw new RuntimeException("unable to open config file");
> }
> PrintWriter pw = new PrintWriter(fo);
> pw.println("X-ML-Name: extremeprogramming-jp");
> pw.println("X-Mail-Count: 00796");
> // ...
> }
>
> 何をテストしているのが伝わってこなかってので、名前を testCorrectConfig に変
> えました。最初に正しいコンフィグファイルを作成します。それから、テストをする
> ようにしました。
>
(太郎さん)
ConfigTestのtestConstructor1()をリファクタリングしよう。
まず、メソッドが長いけれど、これはテスト用のConfigファイル
を準備するところと、実際のテストを行っているところが同じ
メソッドの中にべたっと書いてあるからで、Configファイルを
作成する部分は別にしたほうがいいな。Extract Methodを
適用しよう。
では、
(以下の手順はFowlerのリファクタリングを参照)
リファクタリングその1
1.新たなメソッドの作成
private void createCorrectConfigFile( ) {
}
2.抽出部分のCOPY
private void createCorrectConfigFile( ) {
FileOutputStream fo;
try{
fo = new FileOutputStream("config");
}catch(FileNotFoundException e){
throw new RuntimeException("unable to open config file");
}
PrintWriter pw = new PrintWriter(fo);
pw.println("X-ML-Name: extremeprogramming-jp");
pw.println("Y-ML-Name: extremeprogramming-false");
pw.println("X-Mail-Count: 00796");
pw.println("Y-Mail-Count: 00888");
pw.println("$-MemberList: memberlist");
pw.println("$$-MemberList: memberrrlist");
pw.println("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)");
pw.println("Y-MLServer: fml [fml 2.1_GAMMA#185](not distribute only mode)");
pw.println("X-ML-Info: If you have a question, contact with me");
pw.println("Y-ML-Info: If you have a question, do not contact with me");
pw.close();
try{
fo.close();
}catch(IOException e){
throw new RuntimeException("error on closing config file");
}
}
3.ローカルスコープ変数の拾い出し
FileOutputStream fo;
}catch(FileNotFoundException e){
PrintWriter pw = new PrintWriter(fo);
}catch(IOException e){
の4ヵ所
4.3の変数の使われている場所の確認
4つとも抽出部分だけ
#4つの変数は抽出部分でしか使われいなし、
宣言も抽出部分にあるので、この4つの変数に
ついての特別な考慮は不要
5.現時点でコンパイル
通りました。
6.元の部分から抽出部分を削除して、抽出後
のメソッドの呼び出しに置き換え。
public void testConstructor1(){
createCorrectConfigFile();
Config aConfig = new Config("config");
7.コンパイル
とおりました。
8.テスト
通りました。
リファクタリングその2
次にAdd Parameter(引数の追加)を使って、
private void createCorrectConfigFile( ) {
FileOutputStream fo;
try{
fo = new FileOutputStream("config");
を
private void createCorrectConfigFile(String filename ) {
FileOutputStream fo;
try{
fo = new FileOutputStream(filename);
に
そして、
public void testConstructor1(){
createCorrectConfigFile();
Config aConfig = new Config("config");
を
public void testConstructor1(){
createCorrectConfigFile("config");
Config aConfig = new Config("config");
に
変更
コンパイル、テスト、OK(ステップの詳細は略)
リファクタリングその3
次にRename Method(メソッド名の変更)を使って
public void testConstructor1(){
を
public void testCorrectConfig()
に変更
コンパイル、テスト、OK(ステップの詳細は略)
リファクタリングその4
次にRename Method(メソッド名の変更)を使って
public void testConstructor1(){
を
public void testNoConfigFile(){
に変更
コンパイル、テスト、OK(ステップの詳細は略)
はい、おしまい。testGetName1,2,3も同じようにリファクタリング
できそうだけど、それはまた後のお楽しみにしておこう。
ConfigTest.java全文
/*
* @(#)ConfigTest.java
*/
package XP.jp.co.esm.wiki.extremedomo;
import junit.framework.*;
import java.io.*;
import java.util.*;
public class ConfigTest extends TestCase {
public ConfigTest(String name) {
super(name);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(ConfigTest.class);
}
private void createCorrectConfigFile(String filename) {
FileOutputStream fo;
try{
fo = new FileOutputStream(filename);
}catch(FileNotFoundException e){
throw new RuntimeException("unable to open config file");
}
PrintWriter pw = new PrintWriter(fo);
pw.println("X-ML-Name: extremeprogramming-jp");
pw.println("Y-ML-Name: extremeprogramming-false");
pw.println("X-Mail-Count: 00796");
pw.println("Y-Mail-Count: 00888");
pw.println("$-MemberList: memberlist");
pw.println("$$-MemberList: memberrrlist");
pw.println("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)");
pw.println("Y-MLServer: fml [fml 2.1_GAMMA#185](not distribute only mode)");
pw.println("X-ML-Info: If you have a question, contact with me");
pw.println("Y-ML-Info: If you have a question, do not contact with me");
pw.close();
try{
fo.close();
}catch(IOException e){
throw new RuntimeException("error on closing config file");
}
}
public void testCorrectConfig(){
createCorrectConfigFile("config");
Config aConfig = new Config("config");
assertEquals("test1", "extremeprogramming-jp", aConfig.getName());
Iterator iterator = aConfig.getXInfo();
assertEquals("test2", "X-ML-Name: extremeprogramming-jp", iterator.next( ));
assertEquals("test3", "X-Mail-Count: 00796", iterator.next( ));
assertEquals("test4", "X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)",
iterator.next());
assertEquals("test5", "X-ML-Info: If you have a question, contact with me",
iterator.next());
assert("test6", ! iterator.hasNext());
assertEquals("test7", "memberlist", aConfig.getMemberListFileName());
}
public void testNoConfigFile(){
try{
Config aConfig = new Config("nonconfig");
fail("Should raise an IllegalArgumentException");
}catch(IllegalArgumentException e){
assert(true);
}
}
public void testGetName1(){
FileOutputStream fo;
try{
fo = new FileOutputStream("badconfig");
}catch(FileNotFoundException e){
throw new RuntimeException("unable to open badconfig file");
}
PrintWriter pw = new PrintWriter(fo);
pw.println("Y-ML-Name: extremeprogramming-false");
pw.println("X-Mail-Count: 00796");
pw.println("Y-Mail-Count: 00888");
pw.println("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)");
pw.println("Y-MLServer: fml [fml 2.1_GAMMA#185](not distribute only mode)");
pw.println("X-ML-Info: If you have a question, contact with me");
pw.println("Y-ML-Info: If you have a question, do not contact with me");
pw.close();
try{
fo.close();
}catch(IOException e){
throw new RuntimeException("error on closing badconfig file");
}
Config aConfig = new Config("badconfig");
try{
aConfig.getName();
fail("Should raise an IllegalArgumentException1");
}catch(IllegalArgumentException e){
assert(true);
}
}
public void testGetName2(){
FileOutputStream fo;
try{
fo = new FileOutputStream("badconfig");
}catch(FileNotFoundException e){
throw new RuntimeException("unable to open badconfig file");
}
PrintWriter pw = new PrintWriter(fo);
pw.println("X-ML-Name:");
pw.println("X-Mail-Count: 00796");
pw.println("Y-Mail-Count: 00888");
pw.println("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)");
pw.println("Y-MLServer: fml [fml 2.1_GAMMA#185](not distribute only mode)");
pw.println("X-ML-Info: If you have a question, contact with me");
pw.println("Y-ML-Info: If you have a question, do not contact with me");
pw.close();
try{
fo.close();
}catch(IOException e){
throw new RuntimeException("error on closing badconfig file");
}
Config aConfig = new Config("badconfig");
try{
aConfig.getName();
fail("Should raise an IllegalArgumentException1");
}catch(IllegalArgumentException e){
assert(true);
}
}
public void testGetName3(){
FileOutputStream fo;
try{
fo = new FileOutputStream("badconfig");
}catch(FileNotFoundException e){
throw new RuntimeException("unable to open badconfig file");
}
PrintWriter pw = new PrintWriter(fo);
pw.println("X-ML-Name: ");
pw.println("X-Mail-Count: 00796");
pw.println("Y-Mail-Count: 00888");
pw.println("X-MLServer: fml [fml 2.1_GAMMA#185](distribute only mode)");
pw.println("Y-MLServer: fml [fml 2.1_GAMMA#185](not distribute only mode)");
pw.println("X-ML-Info: If you have a question, contact with me");
pw.println("Y-ML-Info: If you have a question, do not contact with me");
pw.close();
try{
fo.close();
}catch(IOException e){
throw new RuntimeException("error on closing badconfig file");
}
Config aConfig = new Config("badconfig");
try{
aConfig.getName();
fail("Should raise an IllegalArgumentException1");
}catch(IllegalArgumentException e){
assert(true);
}
}
protected void setUp() {
}
protected void tearDown(){
}
}
--
矢崎 博英 <firo@....jp>