001/* 002 * Copyright 2023 the original author or authors. 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package de.cuioss.test.valueobjects.contract; 017 018import static org.junit.jupiter.api.Assertions.assertNotEquals; 019import static org.junit.jupiter.api.Assertions.assertNotNull; 020 021import java.lang.reflect.Method; 022 023import lombok.experimental.UtilityClass; 024 025/** 026 * Simple Helper for reflection-api. Like many other methods of this 027 * test-framework, the methods use rather asserts / {@link AssertionError} to 028 * check preconditions and states than {@link Exception} 029 * 030 * @author Oliver Wolff 031 */ 032@UtilityClass 033public final class ReflectionUtil { 034 035 static final String METHOD_NAME_OBJECT_EQUALS = "equals"; 036 static final String METHOD_NAME_OBJECT_HASH_CODE = "hashCode"; 037 static final String METHOD_NAME_OBJECT_TO_STRING = "toString"; 038 039 /** 040 * Verify the class implements {@link Object#equals(Object)} 041 * 042 * @param clazz class to be checked, msut not be null 043 */ 044 public static void assertEqualsMethodIsOverriden(final Class<?> clazz) { 045 // equals method need an object as parameter 046 final Class<?>[] args1 = new Class[1]; 047 args1[0] = Object.class; 048 049 // get equals method of the class 050 final var method = getMethodFromClass(clazz, METHOD_NAME_OBJECT_EQUALS, args1); 051 final var assertText = "Method 'equals' not implemented in the class : " + clazz.getName(); 052 assertJavaLangObjectMethodWasOverridden(assertText, method); 053 } 054 055 /** 056 * Verify the class implements {@link Object#hashCode()} 057 * 058 * @param clazz class to be checked, must not be null 059 */ 060 public static void assertHashCodeMethodIsOverriden(final Class<?> clazz) { 061 final var method = getMethodFromClass(clazz, METHOD_NAME_OBJECT_HASH_CODE, null); 062 final var assertText = "Method 'hashCode' not implemented in the class : " + clazz.getName(); 063 assertJavaLangObjectMethodWasOverridden(assertText, method); 064 } 065 066 /** 067 * Verify the class implements {@link Object#hashCode()} 068 * 069 * @param clazz class to be checked, must not be null 070 */ 071 public static void assertToStringMethodIsOverriden(final Class<?> clazz) { 072 final var method = getMethodFromClass(clazz, METHOD_NAME_OBJECT_TO_STRING, null); 073 final var assertText = "Method 'toString' not implemented in the class : " + clazz.getName(); 074 assertJavaLangObjectMethodWasOverridden(assertText, method); 075 } 076 077 /** 078 * Check if the method is not a {@link Object} implementation 079 * 080 * @param assertText text to display on fail 081 * @param method {@linkplain Method} to verify 082 */ 083 private static void assertJavaLangObjectMethodWasOverridden(final String assertText, final Method method) { 084 085 assertNotNull(method, assertText); 086 // does java.lang.Object provide the method? 087 assertNotEquals(Object.class, method.getDeclaringClass(), assertText); 088 } 089 090 /** 091 * Retrieve method from class according parameters 092 * 093 * @param clazz class object under test 094 * @param methodName string name of method 095 * @param args1 parameter object for method 096 * @return {@link Method} if exists. if not an assertionError will be thrown. 097 */ 098 private static Method getMethodFromClass(final Class<?> clazz, final String methodName, final Class<?>[] args1) { 099 assertNotNull(clazz, "Target for test is null"); 100 Method result = null; 101 try { 102 if (null != args1) { 103 result = clazz.getMethod(methodName, args1); 104 } else { 105 result = clazz.getMethod(methodName); 106 } 107 } catch (final SecurityException | NoSuchMethodException e) { 108 throw new AssertionError(e); 109 } 110 assertNotNull(result, "Method " + methodName + " does not exist on " + clazz); 111 return result; 112 } 113}