JUnit Excel使い

JavaWorld2005 10月に掲載されていたプログラムを写経
ネットでも配付されてたけど、一応コメントいれてみた。
長いなぁ。
拡張もしないとなぁ。

ターゲットクラス

public class Person {
	String firstName;
	String lastName;
	String title;

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
}

テストクラス

import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

public class PersonTest extends TestCase {
	@SuppressWarnings("unchecked")
	public void testAssertEquals() throws Exception {
		//ファイル名を指定して、期待値を読み込む。
		//setUp()で行ってもよい。
		ExpectedExcel exp = new ExpectedExcel("ExcelTest.xls"); 
		
		//ここはわかりやすくするために一つずつ設定したが、
		//実際にはDBから値を取得する処理などになる
		Person jack = new Person();
		jack.setFirstName("Michael");
		jack.setLastName("Jackson");
		jack.setTitle("Pop");
		Person cathy = new Person();
		cathy.setFirstName("Bob");
		cathy.setLastName("Dylan");
		cathy.setTitle("Rock");
		Person sally = new Person();
		sally.setFirstName("Art");
		sally.setLastName("Blakey");
		sally.setTitle("Jazz");
		
		//比較対象となるデータをMapに格納
		//KEY値はExcelファイルの一行目で指定した文字列
		Map actual = new HashMap();
		actual.put("jack",jack);
		actual.put("cathy",cathy);
		actual.put("sally",sally);
		
		//検証
		//テスト・パターン名を指定して比較
		//パターン名はExcelの一行目で指定した文字列
		exp.assertEquals("test1",actual);
	}
}

Excelを読み込むプログラム

package com.seigi.excel;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import junit.framework.Assert;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExpectedExcel {
    // コンストラクタ
    public ExpectedExcel(String filename) throws IOException {
    populate(filename);
    }

    // 行データオブジェクト
    private class Expectedline {
        String objectName; // Excel_1列目:オブジェクト

        String propertyName; // Excel_2列目:name、titleなどの属性

        String expectedValue; // Excel_テストパターン列:テストデータ

        // 特定行のNULLチェック
        boolean isEmpty() {
            return objectName == null && propertyName == null
                    && expectedValue == null;
        }
    }

    private String[][] table;
    private int patternIdx;
    private int rowIdx;

    /**
     * Excelファイルの読み込み
     * 
     */
    public void populate(String filename) throws IOException {
        InputStream is = getClass().getResourceAsStream(filename);
        // BOOKのオブジェクト作成
        HSSFWorkbook book = new HSSFWorkbook(is);
        is.close();
        // Sheetオブジェクト作成(1つ目のシートを選択)
        HSSFSheet sheet = book.getSheetAt(0);

        // 行オブジェクト(最終行を取得)
        int rows = sheet.getLastRowNum();
        // 列オブジェクト(指定された行の最終セル)
        int columns = sheet.getRow(0).getLastCellNum();

        // テーブルオブジェクトの作成
        table = new String[rows + 1][columns + 1];
        // tableオブジェクトにExcelのデータを格納
        for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
            HSSFRow aRow = sheet.getRow(rowNum);
            if (aRow == null) {
                continue;
            }
            for (int colNum = 0; colNum < aRow.getLastCellNum(); colNum++) {
                HSSFCell valueCell = aRow.getCell((short) colNum);
                if (valueCell != null) {
                    table[rowNum][colNum] = valueCell.getStringCellValue();
                }
            }
        }
    }

    public void patternIs(String patternName) {
        // ヘッダ行(1行目)を指定
        rowIdx = 1;

        // 入力されてテストパターン名が一致するインデックス値をpatternIdxに
        for (int i = 0; i < table[0].length; i++) {
            if (patternName.equals(table[0][i])) {
                patternIdx = i;
                break;
            }
        }
    }

    /**
     * 特定行のデータをかえす 行カウントを+1
     * 
     * @return Expectedline result
     */
    public Expectedline getNext() {
        if (rowIdx >= table.length) {
            return null;
        }
        Expectedline result = new Expectedline();
        result.objectName = table[rowIdx][0];
        result.propertyName = table[rowIdx][1];
        result.expectedValue = table[rowIdx][patternIdx];
        rowIdx++;
        if (result.isEmpty()) {
            return null;
        }
        return result;
    }

    // 
    /**
     * 検証メソッド
     * 
     * @param String
     *            patternName :テストパターン名
     * @param Map
     *            expected :期待するのデータ
     */
    public void assertEquals(String patternName, Map expected)
            throws IllegalArgumentException, IllegalAccessException,
            InvocationTargetException {

        // テストパターン名の列番号を取得
        patternIs(patternName);

        // 行データオブジェクト作成
        Expectedline line;

        // 
        while ((line = getNext()) != null) {

            // 1行データをlineオブジェクトに格納
            // いま指定されている行のオブジェクト名と同じテストデータを取得
            //  (PersonTest.Javaで設定したデータ)
            Object expectedObj = expected.get(line.objectName);

            // 取得したオブジェクトが持っているメソッドを取得(リフレクション)
            // ここでは、Person.javaのメソッド
            Method[] methods = expectedObj.getClass().getMethods();
            Method getter = null;
            for (int i = 0; i < methods.length; i++) {
                if (methods[i].getName().equalsIgnoreCase(
                        "get" + line.propertyName)) {
                    getter = methods[i];
                }
            }

            // Propertyに対するメソッドがなかった場合
            if (getter == null) {
                throw new IllegalArgumentException("property "
                        + line.propertyName + "does not exist on "
                        + line.objectName + "(" + expectedObj + ")");
            }

            // データを取得
            Object value = getter.invoke(expectedObj, new Object[] {});
            if (line.expectedValue == null) {
                Assert.assertEquals("Comparing " + line.objectName + "."
                        + line.propertyName, line.expectedValue, value);
            } else {
                Assert.assertEquals("Comparing " + line.objectName + "."
                        + line.propertyName, line.expectedValue, value
                        .toString());
            }
        }
    }
}