JUnit用と言っていますがhamcrestしか使っていません。
ほとんどテストをしていないのですが、作ったことを忘れてしまいそうなので上げておきます。
使用しているライブラリは下記の通りです。
・hamcrest-core-1.3.jar
・commons-lang3-3.2.1.jar
+各ライブラリで必要なライブラリ
package my.junit.matcher; import org.hamcrest.Matcher; /** * 一部のプロパティを選択してbeanの比較を行えるMatcher * * @author blog owner * * @param <T> * 任意のクラス */ class BeanPropertiesMatcher<T> extends AbstractBeanPropertiesMatcher<T> { /** * コンストラクタ * * @param expected * 予想される値 * @param properties * 比較対象のプロパティ */ BeanPropertiesMatcher(T expected, String... properties) { super(); this.expected = expected; this.properties = properties; } /** * Matcherを取得します。 * * @param expected * 予想される値 * @param propeties * 比較対象のプロパティ * @return 一部のプロパティを選択して比較を行えるMatcher */ public static <T> Matcher<T> equalsValueOf(T expected, String... propeties) { return new BeanPropertiesMatcher<T>(expected, propeties); } }
BeanIgnorePropertiesMatcher.java
package my.junit.matcher; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.ArrayUtils; import org.hamcrest.Matcher; /** * 一部のプロパティを無視してbeanの比較を行えるMatcher * * @author blog owner * * @param <T> * 任意のクラス */ class BeanIgnorePropertiesMatcher<T> extends AbstractBeanPropertiesMatcher<T> { /** * コンストラクタ * * @param expected * 予想される値 * @param ignoreProperties * 比較対象外のプロパティ */ BeanIgnorePropertiesMatcher(T expected, String[] ignoreProperties) { super(); this.expected = expected; if(expected == null){ this.properties = new String[0]; }else{ // 全てのFieldから比較対象外のプロパティを除いたプロパティ配列を作る List<String> properties = new ArrayList<String>(); Field[] fields = expected.getClass().getDeclaredFields(); for (Field field : fields) { if (!ArrayUtils.contains(ignoreProperties, field.getName())) { properties.add(field.getName()); } } this.properties = properties.toArray(new String[properties.size()]); } } /** * Matcherを取得します。 * * @param expected * 予想される値 * @param ignoreProperties * 比較対象外のプロパティ * @return 一部のプロパティを無視して比較を行えるMatcher */ public static <T> Matcher<T> equalsExceptValueOf(T expected, String... ignoreProperties) { return new BeanIgnorePropertiesMatcher<T>(expected, ignoreProperties); } }SelectPropertiesMatcher.java
package my.junit.matcher; import java.util.List; import org.hamcrest.Description; import org.hamcrest.Matcher; interface SelectPropertiesMatcher<T> extends Matcher<T> { /** * 予想される値を取得します。 * * @return 予想される値 */ T getExpected(); /** * 実際の値を取得します。 * * @return 実際の値 */ Object getActual(); /** * 一致しなかったプロパティを取得します。 * * @return 一致しなかったプロパティ */ List<String> getUnmatchProperties(); /** * エラーの場合に表示する、実際の値を示す文字列を追加します。 * * @param description * エラー時の文章 */ public void describeMismatch(Description mismatchDescription); }AbstractBeanPropertiesMatcher.java
package my.junit.matcher; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.reflect.FieldUtils; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; /** * 一部のプロパティを指定してbeanの比較を行えるMatcher * * @author blog owner * * @param <T> * 任意のクラス */ abstract class AbstractBeanPropertiesMatcher<T> extends TypeSafeMatcher<T> implements SelectPropertiesMatcher<T> { /** * 予想される値 */ protected T expected = null; /** * 実際の値 */ protected T actual = null; /** * 比較対象のプロパティ */ protected String[] properties = null; /** * 一致しなかったプロパティ */ protected List<String> unmatchProperties = new ArrayList<String>(); /** * コンストラクタ */ protected AbstractBeanPropertiesMatcher() { } /** * 比較を行います。 * * @param actual * 実際の値 * @return 比較結果 */ @Override public boolean matchesSafely(T actual) { this.actual = actual; if (expected == actual) { // 完全に同じもの return true; } if (expected == null || actual == null) { // 片方だけnullだから違う return false; } // 指定のプロパティを取得しながら比較する for (String property : properties) { Object expectedValue = null; Object actualValue = null; try { // 予測した値 expectedValue = FieldUtils.readDeclaredField(expected, property, true); // 実際の値 actualValue = FieldUtils.readDeclaredField(actual, property, true); } catch (Exception e) { throw new IllegalArgumentException(e); } if (expectedValue == actualValue) { // 完全に同じもの continue; } if (expectedValue == null || actualValue == null) { // 片方だけnullだから違う unmatchProperties.add(property); continue; } if (!expectedValue.equals(actualValue)) { // 違う値 unmatchProperties.add(property); continue; } } // 一致しなかったプロパティがない場合はtrue return unmatchProperties.isEmpty(); } /** * エラーの場合に表示する、実際の値を示す文字列を追加します。 * * @param description * エラー時の文章 */ public void describeMismatch(Description mismatchDescription) { describeMismatchSafely(actual, mismatchDescription); } /** * エラーの場合に表示する、実際の値を示す文字列を追加します。 * * @param actual * 実際の値 * @param description * エラー時の文章 */ @Override public void describeMismatchSafely(T actual, Description mismatchDescription) { setUpDescription(mismatchDescription, actual, unmatchProperties); } /** * エラーの場合に表示する、予測の値を示す文字列を追加します。 * * @param description * エラー時の文章 */ @Override public void describeTo(Description description) { setUpDescription(description, expected, unmatchProperties); } /** * エラーの詳細を設定します。 * * @param description * 設定先 * @param bean * 対象のbean * @param properties * 対象のプロパティ名リスト */ private void setUpDescription(Description description, Object bean, List<String> properties) { if (bean == null) { description.appendValue(null); return; } if (properties.isEmpty()) { description.appendValue(bean.getClass().getName()); return; } int i = -1; for (String property : properties) { i++; if (i != 0) { description.appendText(", "); } description.appendText(property + "="); try { description.appendValue(FieldUtils.readDeclaredField(bean, property, true)); } catch (IllegalAccessException e) { throw new IllegalArgumentException(e); } } return; } /** * 予想される値を取得します。 * * @return 予想される値 */ public T getExpected() { return expected; } /** * 実際の値を取得します。 * * @return 実際の値 */ public Object getActual() { return actual; } /** * 一致しなかったプロパティを取得します。 * * @return 一致しなかったプロパティ */ public List<String> getUnmatchProperties() { return unmatchProperties; } }
0 件のコメント:
コメントを投稿