6月8日

テスト駆動開発でストリームとコレクションを復習する

TextDocumentクラスと、テストケースのTextDocumentTestクラスを作成する。

ファイルを読み込む機能を用意する。
そのために、load()メソッドを作成する。
まずはテストを書く。

TextDocumentTest.java

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.Test;

public class TextDocumentTest {

	@Test
	public void testLoad() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		assertThat(b, is(true));
	}

}

コンパイルエラーを解消するために、TextDocumentクラスにload()メソッドを追加する。
TextDocument.java

public class TextDocument {
	public boolean load(String path) {
		return false;
	}
}

テストを実行するとエラーになるので、load()メソッドの戻り値をtrueに変更する。(Fake)
TextDocument.java

public class TextDocument {
	public boolean load(String path) {
		return true;
	}
}

テストにパスするのでめでたしめでたし。
テストケースに、パスしないテストを追加する。
TextDocumentTest.java

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.Test;

public class TextDocumentTest {

	@Test
	public void testLoadNG() {
		TextDocument td = new TextDocument();
		boolean b = td.load("aaa.txt");
		assertThat(b, is(false));
	}

	@Test
	public void testLoad() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		assertThat(b, is(true));
	}

}

このテストをパスするようにするには、まじめに実装しないといけない。
TextDocument.java

import java.io.File;

public class TextDocument {
	public boolean load(String path) {
		File f = new File(path);
		if (!f.exists()) return false;
		return true;
	}
}

次に、ファイルの行数を取得するメソッドを作ることにする。
hoge.txt は11行なので、テストコードは以下のようになる。
TextDocumentTest.java

	@Test
	public void testLines() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		assertThat(b, is(true));
		int lines = td.getLines();
		assertThat(lines, is(11));
	}

このテストをパスするには、Fakeすればよい。
TextDocument.java

import java.io.File;

public class TextDocument {
	public boolean load(String path) {
		File f = new File(path);
		if (!f.exists()) return false;
		return true;
	}

	public int getLines() {
		return 11;
	}
}

Fakeコードではテストにパスしないようにするために、1行だけのファイル 1.txt を用意し、そのファイルの行数を検査するテストを追加する。
TextDocumentTest.java

	@Test
	public void testLines() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		assertThat(b, is(true));
		int lines = td.getLines();
		assertThat(lines, is(11));
	}

	@Test
	public void testLines1() {
		TextDocument td = new TextDocument();
		boolean b = td.load("1.txt");
		assertThat(b, is(true));
		int lines = td.getLines();
		assertThat(lines, is(1));
	}

このテストをパスするために、TextDocumentクラスをきちんと実装する。
java.util.List を使用してコレクションフレームワークの復習をする。
List の要素として、ファイルの各行を追加する。

TextDocument.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TextDocument {
	private List<String> lines;

	public boolean load(String path) {
		lines = new ArrayList<String>();
		File f = new File(path);
		if (!f.exists()) return false;
		try (BufferedReader in = new BufferedReader(new FileReader(path))) {
			while (in.ready()) {
				String s = in.readLine();
				lines.add(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return true;
	}

	public int getLines() {
		return lines.size();
	}
}

ファイル読み込みができた人は、以下の機能を追加しましょう!

  1. 指定した行の文字列取得
  2. 指定した行を削除(削除した行の文字列を返す)
  3. 指定した文字列を行として末尾に挿入
  4. 指定した場所に指定した文字列を行として挿入
  5. 出力先ファイル名を指定してファイル出力

上記機能追加ができたら、さらに以下の機能を追加しましょう!

  1. 文字列検索(行番号と、その行の文字列を、Listで返す)
  2. 文字列置換(検索と同じように返す)

指定した行の文字列を取得

まずはテストを書く。

TextDocumentTest.java

	@Test
	public void testGetLine() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		String s = td.getLine(0);
		assertThat(s, is("ab"));
	}

TextDocumentにはgetLine()メソッドがないので、Eclipseに作ってもらう。
TextDocument.java

	public String getLine(int i) {
		return null;
	}

テストを実行するとエラーになるので、テストをパスするように “ab”を返すようにFakeする。
TextDocument.java

	public String getLine(int i) {
		return "ab";
	}

テストを追加する。
TextDocumentTest.java

	@Test
	public void testGetLine() {
		TextDocument td = new TextDocument();
		boolean b = td.load("hoge.txt");
		String s = td.getLine(0);
		assertThat(s, is("ab"));
		s = td.getLine(1);
		assertThat(s, is("abc"));
	}

テストを実行するとエラーになるので、テストにパスするようにコードを修正する。
TextDocument.java

	public String getLine(int i) {
		return lines.get(i);
	}

指定した行を削除

まずはテストを書く。
削除した行の文字列を返す。

TextDocumentTest.java

	@Test
	public void testDelete() {
		TextDocument td = new TextDocument();
		td.load("hoge.txt");
		String s = td.deleteLine(0);
		assertThat(s, is("ab"));
	}

EclipseにdeleteLine()メソッドを作ってもらう。
TextDocument.java

	public String deleteLine(int i) {
		return null;
	}

テストを実行してもパスしないので、”ab”を返すようにFakeする。
TextDocument.java

	public String deleteLine(int i) {
		return "ab";
	}

テストを追加する。
1行目を削除したら、もともと2行目だったものが1行目になるはず。
TextDocumentTest.java

	@Test
	public void testDelete() {
		TextDocument td = new TextDocument();
		td.load("hoge.txt");
		String s = td.deleteLine(0);
		assertThat(s, is("ab"));
		s = td.getLine(0);
		assertThat(s, is("abc"));
	}

TextDocumentのdeleteLine()を修正。

TextDocument.java

	public String deleteLine(int i) {
		return lines.remove(i);
	}

指定した文字列を行として末尾に挿入

まずはテストを書く。
1行追加すれば、行数が増えるはず。

TextDocumentTest.java

	@Test
	public void testAdd() {
		TextDocument td = new TextDocument();
		td.load("hoge.txt");
		int lines = td.getLines();
		assertThat(lines, is(10));
		td.addLine("1234567890");
		lines = td.getLines();
		assertThat(lines, is(11));
	}

EclipseにaddLine()を作ってもらう。
テストするとエラーになるので、テストにパスする実装を追加する。
TextDocument.java

	public void addLine(String s) {
		lines.add(s);
	}

指定した場所に指定した文字列を行として挿入

まずはテストを書く。
どこに追加するのかを引数で渡す。
先頭に1行追加すれば、行数が増えるはず。
先頭行は追加した文字列に一致するはず。
2行目は、もともと1行目だった文字列に一致するはず。

TextDocumentTest.java

	@Test
	public void testAdd1() {
		TextDocument td = new TextDocument();
		td.load("hoge.txt");
		int lines = td.getLines();
		assertThat(lines, is(10));
		td.addLine(0, "1234567890");
		lines = td.getLines();
		assertThat(lines, is(11));
		String s = td.getLine(0);
		assertThat(s, is("1234567890"));
		s = td.getLine(1);
		assertThat(s, is("ab"));
	}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です