/*
 * LoggingAspectTest.java
 * Copyright (C) 2008 Cyber Beans Corporation. All rights reserved.
 */
package jp.co.cybec.cb3.aspect;

import java.io.StringWriter;

import jp.co.cybec.cb3.aspect.LoggingAspect;
import jp.co.cybec.cb3.container.provider.ServiceProvider;
import jp.co.cybec.cb3.mock.container.provider.MockServiceProvider;
import jp.co.cybec.cb3.session.RuntimeParameters;
import jp.co.cybec.cb3.session.ServiceParameters;
import junit.framework.Assert;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.WriterAppender;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * LoggingAspectのテストケース。
 * @author Naoko Sugimoto
 */
public class LoggingAspectTest {

	/** テスト用ログライター */
	private StringWriter logWriter = new StringWriter();

	/** アプリケーションコンテキスト */
	private ApplicationContext context = null;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {

		// 設定ファイル読み込み。
		context = new ClassPathXmlApplicationContext(
				new String[]{
						"jp/co/cybec/cb3/aspect/applicationContext.xml"
				}
		);

		// Loggerを作成
		Logger logger = Logger.getLogger(LoggingAspect.class);
		logger.setLevel(Level.INFO);

		// パターンを決定する
		PatternLayout layout = new PatternLayout("%m%n");
		WriterAppender appender = new WriterAppender(layout,logWriter);

		// Appenderを登録
		logger.addAppender(appender);
	}

	/**
	 * {@link jp.co.cybec.cb3.aspect.LoggingAspect#around(org.aspectj.lang.ProceedingJoinPoint)} のためのテスト・メソッド。
	 * 引数に渡されたジョイントポイントのメソッドが実行され、戻り値が返されることを確認する。
	 * また、トレースログが出力されていることを確認する。
	 */
	@Test
	public void testAround() {
		String expectedStartMessage = "[" + MockServiceProvider.class.getName() + "#callService] メソッドを開始します。";
		String expectedEndMessage = "[" + MockServiceProvider.class.getName() + "#callService] メソッドを終了します。";

		// サービスプロバイダを生成。
		ServiceProvider serviceProvider = (ServiceProvider)context.getBean("test");

		// サービスを実行し、戻り値が正しいことを確認する。
		int returnCode = serviceProvider.callService(new ServiceParameters(), new RuntimeParameters(null));
		Assert.assertEquals(0, returnCode);

		// トレースログが出力されていることを確認する。
		StringBuffer logBuffer = logWriter.getBuffer();
		int startMessageIndex = logBuffer.indexOf(expectedStartMessage);
		Assert.assertTrue(startMessageIndex > -1);
		Assert.assertTrue(logBuffer.indexOf(expectedEndMessage) > startMessageIndex);
	}

}
