Index: [Article Count Order] [Thread]

Date:  Mon, 25 Sep 2000 20:20:16 +0900
From:  tetsuya@....jp
Subject:  [XP-jp:00948] MemberList更新&テストツール追	加
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <97BA340C0480D411BDA800062939A1890607B2@....jp>
Posted:  Mon, 25 Sep 2000 20:18:25 +0900
X-Mail-Count: 00948

栗原です。

以下、三郎さんモード。
# 三郎さんは、先のことはあまり考えずにコーディングに走る傾向が見られます:-)

さてと、メンバーリストをファイルから読み込むところを作りますね。
ファイルフォーマットは、メンバーのメールアドレスが1行単位で入っている単純な
ものを想定しているのでしたね。
後々のタスクでは、一時停止のステータスが付加されるかもしれないといっていた
けれど、このタスクでは必要なさそうだから後回しにしておこう。

次に、どのクラスの責任にするかだけど、、、、メンバーリストは全てのメンバー
がメモリにロードされて使用されるだろうから、今あるMemberListにファイルから
のロード機能をつけても問題なさそうだね。

では、テストを追加、、、と。MemberListTestにコードを追加するよ。
ファイル名はコンストラクタで渡すとしておこうか。

    public void testLoadCorrectMemberList1() {
        final String fileName = "correctMemberList1";
        try {
            createCorrectMemberList1(fileName);

            MemberList memberList = new MemberList(fileName);
            assertEquals(firstMember, memberList.get(0));
            assertEquals(secondMember, memberList.get(1));
        } finally {
            deleteMemberList(fileName);
        }
    }
    private void createCorrectMemberList1(String aFileName) {
        BufferedWriter bufOut = null;

        try {
            bufOut = new BufferedWriter(
                new FileWriter(aFileName));

            bufOut.write(firstMember.getMailAddress());
            bufOut.newLine();
            bufOut.write(secondMember.getMailAddress());
            bufOut.newLine();
        } catch (FileNotFoundException e) {
            fail(e.toString());
        } catch (IOException e) {
            fail(e.toString());
        } finally {
            try {
                if (bufOut != null)
                    bufOut.close();
            } catch (Exception e) {
            }
        }
    }
    private void deleteMemberList(String aFileName) {
        File memberList = new File(aFileName);
        memberList.delete();
    }

    private final String nameOfCorrectMemberList1 = "correctMemberList1";

こんな感じでいいよね。
テストが終わったら、使用したテストファイルを消すようにしたんだ。
僕にしては気が利いているだろ?

それと、単なる空行や、スペースのトリム処理ぐらいは確認しておこうか。

    public void testLoadCorrectMemberList2() {
        final String fileName = "correctMemberList2";
        try {
            createCorrectMemberList2(fileName);

            MemberList memberList = new MemberList(fileName);
            assertEquals(firstMember, memberList.get(0));
            assertEquals(secondMember, memberList.get(1));
        } finally {
            deleteMemberList(fileName);
        }
    }
    private void createCorrectMemberList2(String aFileName) {
        BufferedWriter bufOut = null;

        try {
            bufOut = new BufferedWriter(
                new FileWriter(aFileName));

            bufOut.write(firstMember.getMailAddress());
            bufOut.newLine();
            bufOut.newLine();
            bufOut.write("      ");
            bufOut.newLine();
            bufOut.write(secondMember.getMailAddress() + "          ");
            bufOut.newLine();
        } catch (FileNotFoundException e) {
            fail(e.toString());
        } catch (IOException e) {
            fail(e.toString());
        } finally {
            try {
                if (bufOut != null)
                    bufOut.close();
            } catch (Exception e) {
            }
        }
    }

なんか同じようなコードを書いているけど、とりあえずは先に進もうかな。

さて、次はメインのMemberList。
面倒だから、ファイルの解析ロジックを全部コンストラクタ中に書いてしまおう。

    public MemberList(String nameOfMemberList) {
        BufferedReader bufIn = null;

        try {
            bufIn = new BufferedReader(new FileReader(nameOfMemberList));

            String fileLine;
            while (true) {
                fileLine = bufIn.readLine();
                if (fileLine == null)
                    break;

                String mailAddress = fileLine.trim();
                if (mailAddress.length() == 0)
                    continue;

                Member member = new Member(mailAddress);
                add(member);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException();
        } catch (IOException e) {
            throw new RuntimeException();
        } finally {
            try {
                if (bufIn != null)
                    bufIn.close();
            } catch (Exception e) {
            }
        }
    }

かなりアバウトだけど、とりあえずはコンパイルはOK。
それじゃテストするよ、、、、あれ?そうかコンストラクタを定義したためにデフ
ォルトコンストラクタを使用している部分が通らなくなったのか。

とりあえず、、、

    public MemberList() {
    }

を追加して、テストは、、、OKだ。
花子さんが暇をみてリファクタリングするだろうから、次のところに手をつけよう
かな。

以下、素モード:-)

今回の更新はあえて「きれい」にこだわらずにあげました。
抜け落ちているテストもたくさんあるかと思います。

それと、privateフィールドへのアクセス用ヘルパクラスを作成しました。
言い出しっぺの法則です。

暫定的に、パッケージ「testtool」を作らせていただきます。

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo.testtool;

import java.lang.reflect.*;

public class FieldAccessor {
    public static Object get(Object anObject, String aFieldName) {
        try {
            Field field = getAccessibleField(anObject, aFieldName);
            return field.get(anObject);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("failed in access.");
        }
    }
    public static String getString(Object anObject, String aFieldName) {
        try {
            Field field = getAccessibleField(anObject, aFieldName);
            return (String)field.get(anObject);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("failed in access.");
        }
    }
    public static int getInt(Object anObject, String aFieldName) {
        try {
            Field field = getAccessibleField(anObject, aFieldName);
            return field.getInt(anObject);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("failed in access.");
        }
    }
    private static Field getAccessibleField(Object anObject, String
aFieldName) {
        Field result = null;
        try {
            result = anObject.getClass().getDeclaredField(aFieldName);
            result.setAccessible(true);
        } catch (NoSuchFieldException e) {
            throw new IllegalArgumentException(
                "[" + aFieldName + "] is not found.");
        }
        return result;
    }
}

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo.testtool;

import junit.framework.*;

public class FieldAccessorTest extends TestCase {
    public FieldAccessorTest(String name) {
        super(name);
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(FieldAccessorTest.class);
    }

    public void testGetObject() {
        Object val = FieldAccessor.get(this, "objectField");
        assertEquals(objectField, val);
    }
    public void testGetString() {
        String val = FieldAccessor.getString(this, "stringField");
        assertEquals(stringField, val);
    }
    public void testGetInt() {
        int val = FieldAccessor.getInt(this, "intField");
        assertEquals(intField, val);
    }

    private Object objectField = new Object();
    private String stringField = new String("accessor test");
    private int intField = 256;
}

現在の実装で取得できないクラスがあったらそのときにgetterを追加します。
setterも必要であればそのときに。

それと、MemberList, MemberListTestの全ては以下のとおり。
# 今後、ソースの全ての添付は行うべきでないようでしたら、助言をお願いします。
# 追加部分のみを書いてCVSで管理したほうがいいのかな?

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo;

import java.util.*;
import java.io.*;

public class MemberList {
    public MemberList() {
    }
    public MemberList(String nameOfMemberList) {
        BufferedReader bufIn = null;

        try {
            bufIn = new BufferedReader(new FileReader(nameOfMemberList));

            String fileLine;
            while (true) {
                fileLine = bufIn.readLine();
                if (fileLine == null)
                    break;

                String mailAddress = fileLine.trim();
                if (mailAddress.length() == 0)
                    continue;

                Member member = new Member(mailAddress);
                add(member);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException();
        } catch (IOException e) {
            throw new RuntimeException();
        } finally {
            try {
                if (bufIn != null)
                    bufIn.close();
            } catch (Exception e) {
            }
        }
    }
    public void add(Member aMember) {
        if (contains(aMember))
            throw new IllegalArgumentException();

        members.add(aMember);
    }
    public Member get(int index) {
        return (Member)members.get(index);
    }
    public int size() {
        return members.size();
    }
    public boolean contains(Member aMember) {
        return members.contains(aMember);
    }

    private List members = new ArrayList();
}

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo;

import junit.framework.*;

import java.io.*;

public class MemberListTest extends TestCase {
    public MemberListTest(String name) {
        super(name);
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(MemberListTest.class);
    }

    public void testLoadCorrectMemberList1() {
        final String fileName = "correctMemberList1";
        try {
            createCorrectMemberList1(fileName);

            MemberList memberList = new MemberList(fileName);
            assertEquals(firstMember, memberList.get(0));
            assertEquals(secondMember, memberList.get(1));
        } finally {
            deleteMemberList(fileName);
        }
    }
    public void testLoadCorrectMemberList2() {
        final String fileName = "correctMemberList2";
        try {
            createCorrectMemberList2(fileName);

            MemberList memberList = new MemberList(fileName);
            assertEquals(firstMember, memberList.get(0));
            assertEquals(secondMember, memberList.get(1));
        } finally {
            deleteMemberList(fileName);
        }
    }
    public void testNewMemberList() {
        MemberList memberList = new MemberList();
        assertEquals(memberList.size(), 0);
    }
    public void testOneMemberList() {
        MemberList memberList = new MemberList();
        memberList.add(firstMember);
        assertEquals(memberList.size(), 1);
    }
    public void testDuplicationMember() {
        MemberList memberList = new MemberList();
        memberList.add(firstMember);
        try {
            memberList.add(firstMember);
            fail("Should raise an IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            assert(true);
        }
    }
    public void testGetMember() {
        MemberList memberList = new MemberList();
        memberList.add(firstMember);
        memberList.add(secondMember);
        assertEquals(firstMember, memberList.get(0));
    }
    public void testContains(){
        MemberList memberList = new MemberList();

        Member thirdMember = new Member("ggg@....iii");
        Member forthMember = new Member("jjj@....lll");
        Member fifthMember = new Member("aaa@....ccc");
        Member sixthMember = new Member("ddd@....fff");

        memberList.add(firstMember);
        memberList.add(secondMember);
        memberList.add(thirdMember);

        assert("test1", memberList.contains(firstMember));
        assert("test2", memberList.contains(secondMember));
        assert("test3", memberList.contains(thirdMember));
        assert("test4", !memberList.contains(forthMember));
        assert("test5", memberList.contains(fifthMember));
        assert("test6", memberList.contains(sixthMember));
    }
    protected void setUp() {
        firstMember = new Member("aaa@....ccc");
        secondMember = new Member("ddd@....fff");
    }

    private void createCorrectMemberList1(String aFileName) {
        BufferedWriter bufOut = null;

        try {
            bufOut = new BufferedWriter(
                new FileWriter(aFileName));

            bufOut.write(firstMember.getMailAddress());
            bufOut.newLine();
            bufOut.write(secondMember.getMailAddress());
            bufOut.newLine();
        } catch (FileNotFoundException e) {
            fail(e.toString());
        } catch (IOException e) {
            fail(e.toString());
        } finally {
            try {
                if (bufOut != null)
                    bufOut.close();
            } catch (Exception e) {
            }
        }
    }
    private void createCorrectMemberList2(String aFileName) {
        BufferedWriter bufOut = null;

        try {
            bufOut = new BufferedWriter(
                new FileWriter(aFileName));

            bufOut.write(firstMember.getMailAddress());
            bufOut.newLine();
            bufOut.newLine();
            bufOut.write("      ");
            bufOut.newLine();
            bufOut.write(secondMember.getMailAddress() + "          ");
            bufOut.newLine();
        } catch (FileNotFoundException e) {
            fail(e.toString());
        } catch (IOException e) {
            fail(e.toString());
        } finally {
            try {
                if (bufOut != null)
                    bufOut.close();
            } catch (Exception e) {
            }
        }
    }
    private void deleteMemberList(String aFileName) {
        File memberList = new File(aFileName);
        memberList.delete();
    }

    private final String nameOfCorrectMemberList1 = "correctMemberList1";
    private final String nameOfCorrectMemberList2 = "correctMemberList2";

    private Member firstMember;
    private Member secondMember;
}

---
Tetsuya Kurihara
tetsuya@....jp