朝練のソレの試験を書いてみる

ええと、junit4 を使ってみたかったので。
ちなみに 10.5.8 な OSX だと java の環境がダメダメなので途中で断念。あの OS は基本的に Xcodeobjective-c で、に限定されているとしか思えん。

追記

このエントリ、書きかけで意識を失なっております。そのまま投入w

方針

  • 試験なクラスは試験対象なクラスがいるパケジに混在させる方向

という事が考えかたとして正しいのかどうかは別として試しに試験を書いて実行してみた。ちなみに 10.5.8 な OSX はこの時点でどうにもならなくなりました。
クラス定義が以下です。

package jp.co.lexues.study.refactoring;

public class Movie {
	
	public static final int CHILDRENS = 2;
	public static final int REGULAR = 0;
	public static final int NEW_RELEASE = 1;
	
	private String _title;
	private int _priceCode;
	
	public Movie(String title, int priceCode) {
		_title = title;
		_priceCode = priceCode;
	}

	public int getPriceCode() {
		return _priceCode;
	}
	
	public void setPriceCode(int arg) {
		_priceCode = arg;
	}
	
	public String getTitle() {
		return _title;
	}
}

とりあえず書いてみた試験が以下。

package jp.co.lexues.study.refactoring;


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class MovieTest {
	private Movie movie;
	private final String movieTitle = "E.T";

	@Before
	public void setUp() throws Exception {
		movie = new Movie(movieTitle, Movie.NEW_RELEASE);
	}

	@Test
	public void movieGetterTest() {
		assertEquals(movieTitle, movie.getTitle());
	}
}

一発で動きました。どんどん書こう。試験書くのって気持ちイイんだよね、と言いつつ以下。

package jp.co.lexues.study.refactoring;


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class MovieTest {
	private Movie movie;
	private final String movieTitle = "E.T";

	@Before
	public void setUp() throws Exception {
		movie = new Movie(movieTitle, Movie.NEW_RELEASE);
	}

	@Test
	public void movieGetterTest() {
		assertEquals(movieTitle, movie.getTitle());
		assertEquals(Movie.NEW_RELEASE, movie.getPriceCode());
	}
	
	@Test
	public void setPriceCodeTest() {
		assertEquals(Movie.NEW_RELEASE, movie.getPriceCode());
		movie.setPriceCode(Movie.CHILDRENS);
		assertEquals(Movie.CHILDRENS, movie.getPriceCode());
		movie.setPriceCode(Movie.REGULAR);
		assertEquals(Movie.REGULAR, movie.getPriceCode());
	}
}

うーむ。とりあえず次。

package jp.co.lexues.study.refactoring;

class Rental {
	
	private Movie _movie;
	private int _daysRented;
	
	public Rental(Movie movie, int daysRented) {
		_movie = movie;
		_daysRented = daysRented;
	}

	public int getDaysRented() {
		return _daysRented;
	}
	
	public Movie getMovie() {
		return _movie;
	}
}

これもコンストラクタと getter しかありませんな。こんなもんか。

package jp.co.lexues.study.refactoring;


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class RentalTest {
	private Rental rental;
	private Movie movie;
	private final String movieTitle = "E.T";
	private final int daysRented = 5;

	@Before
	public void setUp() throws Exception {
		movie = new Movie(movieTitle, Movie.CHILDRENS);
		rental = new Rental(movie, daysRented);
	}
	
	@Test
	public void getDaysRentedTest() {
		assertEquals(daysRented, rental.getDaysRented());
	}

	@Test
	public void getMovieTest() {
		assertEquals(movie, rental.getMovie());
	}
}

最後のがハードル高い。定義が以下。

package jp.co.lexues.study.refactoring;

import java.util.Enumeration;
import java.util.Vector;

class Customer {
	private String _name;
	private Vector<Rental> _rentals = new Vector<Rental>();
	
	public Customer(String name) {
		_name = name;
	}
	
	public void addRental(Rental arg) {
		_rentals.addElement(arg);
	}
	
	public String getName() {
		return _name;
	}
	
	public String statement() {
		double totalAmount = 0;
		int frequentRenterPoints = 0;
		Enumeration<Rental> rentals = _rentals.elements();
		String result = "Rental Record for " + getName() + "\n";
		
		while (rentals.hasMoreElements()) {
			double thisAmount = 0;
			Rental each = (Rental) rentals.nextElement();
			
			switch (each.getMovie().getPriceCode()) {
				case Movie.REGULAR:
					thisAmount += 2;
					if (each.getDaysRented() > 2)
						thisAmount += (each.getDaysRented() - 2) * 1.5;
					break;
				case Movie.NEW_RELEASE:
					thisAmount += each.getDaysRented() * 3;
					break;
				case Movie.CHILDRENS:
					thisAmount += 1.5;
					if (each.getDaysRented() > 3)
						thisAmount += (each.getDaysRented() - 3) * 1.5;
					break;
			}
			
			frequentRenterPoints++;

			if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE &&
					each.getDaysRented() > 1)) frequentRenterPoints++;
			
			result += "\t" + each.getMovie().getTitle() + "\t" +
				String.valueOf(thisAmount) + "\n";
			totalAmount += thisAmount;
		}
		
		result += "Amount owed is " + String.valueOf(totalAmount) + "\n";
		result += "You earned " + String.valueOf(frequentRenterPoints) +
			" frequent renter points";
		return result;
	}
 }

とりあえずコンストラクタとそこで設定される属性の getter の試験は簡単に書けるか。

package jp.co.lexues.study.refactoring;


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class CustomerTest {
	private Customer customer;
	private final String name = "yamanetoshi";
	private final String movieTitle = "E.T";
	private final int dayRented = 5;

	@Before
	public void setUp() throws Exception {
	}
	
	@Test
	public void getNameTest() {
		customer = new Customer(name);
		assertEquals(name, customer.getName());
	}

}

これ、単体試験てきには Movie の PriceCode 毎に正しい値が出ているか、と加算がきちんとできてるか、って事が確認できてれば OK かな。
出力 (というか戻り) が文字列ってあたりが微妙w
てか、中で色々細かい処理してて試験作るの大変だな、ってだけでリファクタリングのモチベーションになり得ると思うんですが違うかなw
とりあえず簡単なソレのみ。

package jp.co.lexues.study.refactoring;


import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class CustomerTest {
	private Customer customer;
	private final String name = "yamanetoshi";
	private final String movieTitle = "E.T";
	private final int dayRented = 5;

	@Before
	public void setUp() throws Exception {
	}
	
	@Test
	public void getNameTest() {
		customer = new Customer(name);
		assertEquals(name, customer.getName());
	}

}

面倒臭いのはここからなんですが、続けるリキが微妙。