/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.framework.unit; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.internal.runners.InitializationError; import org.seasar.framework.unit.impl.IntrospectorUtil; /** * メソッドを検証するクラスです。 * * @author taedium */ public class S2MethodValidator { /** テストクラス */ protected Class<?> clazz; /** 検証に違反したときに発生するスロー可能オブジェクトのリスト */ protected List<Throwable> errors = new ArrayList<Throwable>(); /** * インスタンスを構築します。 * * @param clazz */ public S2MethodValidator(Class<?> clazz) { this.clazz = clazz; } /** * インスタンスメソッドを検証します。 */ public void validateInstanceMethods() { validateTestMethods(After.class, false); validateTestMethods(Before.class, false); validateTestMethods(Test.class, false); } /** * スタティックメソッドを検証します。 */ public void validateStaticMethods() { validateTestMethods(BeforeClass.class, true); validateTestMethods(AfterClass.class, true); } /** * デフォルトのランナーに対し、メソッドを検証します。 * * @return スロー可能オブジェクトのリスト */ public List<Throwable> validateMethodsForDefaultRunner() { validateNoArgConstructor(); validateStaticMethods(); validateInstanceMethods(); return errors; } /** * 検証の結果エラーがないことをアサートします。 * * @throws InitializationError * 検証で何らかのエラーが発生した場合 */ public void assertValid() throws InitializationError { if (!errors.isEmpty()) throw new InitializationError(errors); } /** * 引数なしのコンストラクタがあることを検証します。 */ public void validateNoArgConstructor() { try { clazz.getConstructor(); } catch (Exception e) { errors.add(new Exception( "Test class should have public zero-argument constructor", e)); } } /** * テストメソッドを検証します。 * * @param annotation * アノテーション * @param isStatic * スタティックなメソッドであれば<code>true</code> */ protected void validateTestMethods(Class<? extends Annotation> annotation, boolean isStatic) { List<Method> methods = IntrospectorUtil.getAnnotatedMethods(clazz, annotation); for (Method each : methods) { if (Modifier.isStatic(each.getModifiers()) != isStatic) { String state = isStatic ? "should" : "should not"; errors.add(new Exception("Method " + each.getName() + "() " + state + " be static")); } if (!Modifier.isPublic(each.getDeclaringClass().getModifiers())) errors.add(new Exception("Class " + each.getDeclaringClass().getName() + " should be public")); if (!Modifier.isPublic(each.getModifiers())) errors.add(new Exception("Method " + each.getName() + " should be public")); if (each.getReturnType() != Void.TYPE) errors.add(new Exception("Method " + each.getName() + " should be void")); if (each.getParameterTypes().length != 0) errors.add(new Exception("Method " + each.getName() + " should have no parameters")); } } }