5月13日

レッドブルを購入するテストがうまくいかなかったので、購入できるかどうかを調べてみるために、isPurchasable()を追加してみる。

	@Test
	public void testレッドブルを購入する() {
		VendingMachine vm = new VendingMachine();
		RedBull r = (RedBull) vm.purchase("レッドブル");
		assertNull(r);
		vm.insert(200);
		boolean b = vm.isPurchasable("レッドブル");
		assertEquals(true, b);
		r = (RedBull) vm.purchase("レッドブル");
		assertNotNull(r);
	}

購入できないといわれるので、原因がどこかを考える。

200円を投入しているけど、200円玉などない!ので、お金が入ってない!

	@Test
	public void testレッドブルを購入する() {
		VendingMachine vm = new VendingMachine();
		RedBull r = (RedBull) vm.purchase("レッドブル");
		assertNull(r);
		vm.insert(100);
		vm.insert(100);
		boolean b = vm.isPurchasable("レッドブル");
		assertEquals(true, b);
		r = (RedBull) vm.purchase("レッドブル");
		assertNotNull(r);
	}

100円を2回投入すれば買えるようになった。

最後に、3種類の飲み物を購入してみる。
売上高とおつりを確認して終わりとする。

	@Test
	public void test複数の飲み物を購入する() {
		VendingMachine vm = new VendingMachine();
		vm.insert(1000);
		Coke c = (Coke) vm.purchase("コーラ");
		assertNotNull(c);
		Water w = (Water) vm.purchase("水");
		assertNotNull(w);
		RedBull r = (RedBull) vm.purchase("レッドブル");
		assertNotNull(r);
		int sa = vm.getSaleAmount();
		assertEquals(420, sa);
		int amount = vm.getAmount();
		assertEquals(580, amount);
		int change = vm.refund();
		assertEquals(580, change);
	}

テキスト16章

ストリームは、Javaがデータの入出力を行うための概念。

まずはファイルから文字列を読み書きするサンプルを作成してみる。

Filer.java

package tdd;

public class Filer {
	public long read(String name) {
		return 0;
	}
}

ファイルを読み込んでバイト数を返すメソッドread()を作ってみる。

テストを書く。

package tdd;

import static org.junit.Assert.*;

import java.io.IOException;

import org.junit.Test;

public class FilerTest {

	@Test
	public void testRead() {
		Filer f = new Filer();
		long l;
		l = f.read("Coke.java");
		assertEquals(56, l);
	}
}

テストにパスするようにコードを修正する。

package tdd;

public class Filer {
	public long read(String name) {
		return 56;
	}
}

テストを追加する。

package tdd;

import static org.junit.Assert.*;

import java.io.IOException;

import org.junit.Test;

public class FilerTest {

	@Test
	public void testRead() {
		Filer f = new Filer();
		long l;
		l = f.read("Coke.java");
		assertEquals(56, l);
		l = f.read("Drink.java");
		assertEquals(52, l);
	}
}

実際のファイルにアクセスするようコードを修正。

package tdd;

import java.io.FileReader;
import java.io.IOException;

public class Filer {
	public long read(String name) throws IOException {
		long l = 0;
		FileReader r = new FileReader(name);
		return 56;
	}
}

例外をスローするので、テスト側も修正。
FileNotFoundExceptionを無視しないようにするため、RuntimeExceptionを作り直してスローして、テストケースが例外を認識できるようにする。

package tdd;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class FilerTest {

	@Test
	public void testRead() {
		Filer f = new Filer();
		long l;
		try {
			l = f.read("Coke.java");
			assertEquals(56, l);
			l = f.read("Drink.java");
			assertEquals(52, l);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}

作業ディレクトリを調べるためのコードを追加。

package tdd;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class FilerTest {

	@Test
	public void testRead() {
		File cd = new File(".");
		System.out.println(cd.getAbsolutePath());
		Filer f = new Filer();
		long l;
		try {
			l = f.read("Coke.java");
			assertEquals(56, l);
			l = f.read("Drink.java");
			assertEquals(52, l);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}

作業ディレクトリからの相対パスでファイルを指定するようにテストコードを修正。

package tdd;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class FilerTest {

	@Test
	public void testRead() {
		File cd = new File(".");
		System.out.println(cd.getAbsolutePath());
		Filer f = new Filer();
		long l;
		try {
			l = f.read("src/tdd/Coke.java");
			assertEquals(56, l);
			l = f.read("src/tdd/Drink.java");
			assertEquals(52, l);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}

FileNotFoundExceptionが出なくなった。

実際にバイト数を数えるようにFilerを修正する。

Java7から使えるようになった、try-with-resources構文を使用してコードを記述する。

package tdd;

import java.io.FileReader;
import java.io.IOException;

public class Filer {
	public long read(String name) throws IOException {
		long l = 0;
		try (FileReader r = new FileReader(name);) {
			while (true) {
				int c = r.read();
				if (c < 0) break;
				l++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return l;
	}
}

テストにパスしたので、バイト数を正しく数えているらしい。

ファイルをコピーする機能を追加してみる。
空のメソッドを作成する。

	public long copy(String src, String dst) {
		return 0;
	}

テストを作成。コピーしたバイト数を返すことにする。

	@Test
	public void testCopy() {
		Filer f = new Filer();
		long l;
		l = f.copy("src/tdd/Coke.java", "Coke.java");
		assertEquals(56, l);
	}

copy() メソッドを実装する。

	public long copy(String src, String dst) {
		long l = 0;
		try (FileReader r = new FileReader(src);
			 FileWriter w = new FileWriter(dst);) {
			while (true) {
				int c = r.read();
				if (c < 0) break;
				l++;
				w.write(c);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return l;
	}

テストを実行すると、テストにパスする。
パッケージエクスプローラでプロジェクト名を右クリックし、「リフレッシュ」を選択すると、Coke.javaがtddプロジェクトの直下に現れる。

指定したURLのコンテンツをダウンロードするdownload() メソッドの追加。

	public void download(String url, String dst) {
		return;
	}

ダウンロードのテストを作成する。
Yahooのトップページをダウンロードしたらファイルのサイズが1000バイト以上あるだろう?

	@Test
	public void testDownload() {
		Filer f = new Filer();
		long l;
		f.download("http://www.yahoo.co.jp", "yahoo.html");
		File html = new File("yahoo.html");
		assertTrue(html.length() > 1000);
	}

download()メソッドを実装する。
URLクラスのopenStream()メソッドを呼ぶことで、コンテンツにアクセスする入力ストリームを取得できる。
入力ストリームから読み込んだ内容をファイルに出力すればよい。

	public void download(String url, String dst) throws IOException {
		long l = 0;
		URL u = new URL(url);
		try (InputStream is = u.openStream();
			 FileOutputStream os = new FileOutputStream(dst);) {
			while (true) {
				int c = is.read();
				if (c < 0) break;
				l++;
				os.write(c);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return;
	}

パッケージエクスプローラでプロジェクト名を右クリックし、「リフレッシュ」を選択すると、yahoo.htmlがtddプロジェクトの直下に現れる。

ファイルを開くと、HTMLがダウンロードできていることがわかる。

コメントを残す

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