JUnit実践入門を読んで:コード補足その1

渡辺修司さん著の「JUnit実践入門」を読んで、写経して、コードが本に載っていなかったり、ダウンロードしたサンプルに入っていなかったりしたので、自分なりに考えて補足しました。

第一段
第20章 テストダブルの活用 20.1 システムに依存するテスト

リスト20.3に対するテストコードがないので、下記に記します。テスト対象コードのクラス名はMonthlyCalendar2とします。テストコードでは、MonthlyCalendar2を継承する無名クラスで、geCalendarメソッドをオーバーライドします。

package ch20.ex01;

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

import java.util.Calendar;

import org.junit.Test;


public class MonthlyCalendar2Test {

	@Test
	public void 現在時刻が20120131の場合getRemainingDaysは0を返す() throws Exception {
		MonthlyCalendar2 sut
		= new MonthlyCalendar2() {
			@Override
			Calendar getCalendar() {
				return newCalendar(2012, 1, 31);
			}
		};
		assertThat(sut.getRemainingDays(), is(0));
	}

	@Test
	public void 現在時刻が20120130の場合getRemainingDaysは1を返す() throws Exception {
		MonthlyCalendar2 sut
		= new MonthlyCalendar2() {
			@Override
			Calendar getCalendar() {
				return newCalendar(2012, 1, 30);
			}
		};
		assertThat(sut.getRemainingDays(), is(1));
	}

	@Test
	public void 現在時刻が20120201の場合getRemainingDaysは28を返す() throws Exception {
		MonthlyCalendar2 sut
		= new MonthlyCalendar2() {
			@Override
			Calendar getCalendar() {
				return newCalendar(2012, 2, 1);
			}
		};
		assertThat(sut.getRemainingDays(), is(28));
	}

	static Calendar newCalendar(int yyyy, int mm, int dd) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, yyyy);
		cal.set(Calendar.MONTH, mm - 1);
		cal.set(Calendar.DATE, dd);
		cal.set(Calendar.HOUR, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal;
	}

}

リスト20.4のテストコードを作って、テストをしようとしましたが、リスト20.4のコードだと、私はテストコードが書けませんでした。修正したテスト対象コードは次のようになりました。

テスト対象コード

package ch20.ex01;

import java.util.Calendar;

interface SystemCalendar {
	Calendar getInstance();
}

public class MonthlyCalendar3 implements SystemCalendar {
	@Override
	public Calendar getInstance() {
		return Calendar.getInstance();
	}
}

そして、テストコードは、下記のようになりました。テストで制御できない処理を別のクラスに移譲するのですが、その移譲クラスでgetRemainingDaysメソッドを実装しました。

package ch20.ex01;

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

import java.util.Calendar;

import org.junit.Test;

public class MonthlyCalendar3Test {

	@Test
	public void 現在時刻が20120131の場合getRemainingDaysは0を返す() throws Exception {
				
		DelegateObjectExample sut = new DelegateObjectExample();
		sut.setDate(2012, 1, 31);
		assertThat(sut.getRemainingDays(), is(0));
	}
	
	@Test
	public void 現在時刻が20120130の場合getRemainingDaysは1を返す() throws Exception {
		DelegateObjectExample sut = new DelegateObjectExample();
		sut.setDate(2012, 1, 30);
		assertThat(sut.getRemainingDays(), is(1));
	}
	
	@Test
	public void 現在時刻が20120201の場合getRemainingDaysは28を返す() throws Exception {
		DelegateObjectExample sut = new DelegateObjectExample();
		sut.setDate(2012, 2, 1);
		assertThat(sut.getRemainingDays(), is(28));
	}
}

class DelegateObjectExample {
	SystemCalendar sysCal = new MonthlyCalendar3();
	Calendar cal;
			
	public void setDate(int yyyy, int mm, int dd) {
		cal = sysCal.getInstance();
		cal = newCalendar(yyyy, mm, dd);
	}
	
	public int getRemainingDays() {
        return cal.getActualMaximum(Calendar.DATE) - cal.get(Calendar.DATE);
    }
	
	static Calendar newCalendar(int yyyy, int mm, int dd) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, yyyy);
		cal.set(Calendar.MONTH, mm - 1);
		cal.set(Calendar.DATE, dd);
		cal.set(Calendar.HOUR, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal;
	}
}

コメントを残す

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