モックとスタブの違い 状態中心のテスト

状態中心のテスト

2つのスタイルを簡単な例で説明するところから始めようと思う(この例はJavaで書かれているが、どのオブジェクト指向言語でもこの原理は通用する)。オーダー[注文]オブジェクトを取得して、倉庫オブジェクトから注文を引き当てるようにしたい。オーダーオブジェクトはとてもシンプルで、一つの商品と一つの数量を持つだけだ。倉庫はいろいろな商品の在庫を持っている。あるオーダーに対して倉庫で引当をしようとする時、2つの対応が考えられる。もし倉庫にオーダーに引き当てるのに十分な商品があれば、オーダーは引き当てられて、その分倉庫の商品数は減る。もし倉庫に十分な商品がなければ、オーダーは成り立たないで、倉庫では何も起きない。

この2つの振る舞いは2つのテストが必要なことも意味していて、そのテストはJUnitでは非常によく行われるテストと似ている。

public class OrderStateTester extends TestCase {	
	private static String TALISKER = "talisker";
	private static String HIGHLAND_PARK = "Highland Park";
	private Warehouse warehouse = new WarehouseImpl();

	protected void setUp() throws Exception {
		warehouse.add(TALISKER, 50);
		warehouse.add(HIGHLAND_PARK, 25);
	}
	public void testOrderIsFilledIfEnoughInWarehouse() {
		Order order = new Order(TALISKER, 50);
		order.fill(warehouse);
		assertTrue(order.isFilled());
		assertEquals(0, warehouse.getInventory(TALISKER));
	}
	public void testOrderDoesNotRemoveIfNotEnough() {
		Order order = new Order(TALISKER, 51);
		order.fill(warehouse);
		assertFalse(order.isFilled());
		assertEquals(50, warehouse.getInventory(TALISKER));
	}
}

状態中心のテストは典型的なパターンで行われる。まずテストが必要なオブジェクトをまとめてセットアップする。これらのオブジェクトにはテストしているメインのオブジェクトも含まれているが、テストを行うためメインのオブジェクトが使う、その他のオブジェクトも含まれる。このオブジェクトのコレクション [=メインのオブジェクトが使うオブジェクトのまとまり] はフィクスチャ [付属品] と呼ばれる。上の例では、フィクスチャの中に1つだけ副次的なオブジェクトがあるだけでよかったが、普通はフィクスチャに非常にたくさんのオブジェクトを持つ。こういったフィクスチャはJUnitではsetUpメソッドの中でセットアップされることが多い。

フィクスチャのセットアップを行ったら、メインのオブジェクトをテストしたい処理を行うようにして起動する。処理が終わったら、今度は全てがうまくいったかを調べないといけない。複数のアサート文を使うことで調べられるこのこと[=うまくいっているということ]は、メインのオブジェクトとテストで注意を向けるサブオブジェクトに対して調べられる。上の例では、メインオブジェクトとしてorderを、サブオブジェクトとしてwarehouseオブジェクトを検査している。

メインのオブジェクトとサブオブジェクトの区別は、状態中心のテストではちょっと曖昧だ。しかし私は、メインオブジェクトは重点的にテストされるオブジェクト、サブオブジェクトはそれについてのテストが他にあり、今のテストでは正常に機能すると仮定されるオブジェクト、と考える。複数のメインオブジェクトがある場合があるだろうが、この論文での趣旨のため、単一のメインオブジェクトを扱うことにする。