All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.meanbean.test.BeanPropertyTester Maven / Gradle / Ivy

/*-
 * ​​​
 * meanbean
 * ⁣⁣⁣
 * Copyright (C) 2010 - 2020 the original author or authors.
 * ⁣⁣⁣
 * 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.meanbean.test;

import org.meanbean.bean.info.PropertyInformation;
import org.meanbean.logging.$Logger;
import org.meanbean.logging.$LoggerFactory;
import org.meanbean.test.internal.EqualityTest;
import org.meanbean.util.AssertionUtils;
import org.meanbean.util.ValidationHelper;

import java.lang.reflect.Type;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * An object that tests a Bean's property methods.
 * 
 * @author Graham Williamson
 */
public class BeanPropertyTester {

	/**
	 * 

* Test the property specified by the propertyInformation parameter on the specified bean object using the specified * testValue. *

* *

* The test is performed by setting the property of the specified bean to the specified testValue via the property * setter method, then getting the value of the property via the property getter method and asserting that the * obtained value matches the testValue. This tests the getter and setter methods of the property. *

* * @param bean * The object the property should be tested on. * @param property * Information about the property to be tested. * @param testValue * The value to use when testing the property. * @param equalityTest * The equality test to perform during testing: Logical (logically equivalence, that is x.equals(y)) or * Absolute (that is x == y). * * @throws IllegalArgumentException * If any of the parameters are deemed illegal. For example, if any are null, if the * property is not readable and writable, or if the type of the testValue does not match the property * type. * @throws AssertionError * If the test fails. * @throws BeanTestException * If an unexpected exception occurs during testing. */ public void testProperty(Object bean, PropertyInformation property, Object testValue, EqualityTest equalityTest) throws IllegalArgumentException, AssertionError, BeanTestException { ValidationHelper.ensureExists("bean", "test property", bean); ValidationHelper.ensureExists("property", "test property", property); ValidationHelper.ensureExists("testValue", "test property", testValue); ValidationHelper.ensureExists("equalityTest", "test property", equalityTest); String propertyName = property.getName(); if (!property.isReadableWritable()) { throw new IllegalArgumentException("Cannot test property [" + propertyName + "] - property must be readable and writable."); } if (!typesAreCompatible(testValue.getClass(), property.getWriteMethodParameterType())) { String msg = String.format("Cannot test property [%s] - testValue must be same type as property. Expected %s but found %s", propertyName, testValue.getClass(), property.getWriteMethodParameterType()); throw new IllegalArgumentException(msg); } try { property.getWriteMethod().invoke(bean, testValue); Object readMethodOutput = property.getReadMethod().invoke(bean); UrlEqualityTestWarning.ifNeeded(equalityTest, bean, propertyName, testValue); UrlEqualityTestWarning.ifNeeded(equalityTest, bean, propertyName, readMethodOutput); if (!equalityTest.test(testValue, readMethodOutput)) { String message = "Property [" + propertyName + "] getter did not return test value. Expected [" + testValue + "] but getter returned [" + readMethodOutput + "]."; AssertionUtils.fail(message); } } catch (Exception e) { throw throwException(property, e); } } static BeanTestException throwException(PropertyInformation property, Exception e) { String propertyName = property.getName(); String message = "Failed to test property [" + propertyName + "] due to Exception [" + e.getClass().getName() + "]: [" + e.getMessage() + "]."; throw new BeanTestException(message, e); } /** * Are the specified compatible? * * @param classA * A type to compare. * @param superType * Another type to compare. If it is possible that one of the types might be a superclass of the other, * specify that type here. * * @return true if the specified types are compatible; false otherwise. */ protected boolean typesAreCompatible(Class classA, Type superType) { Class superClass = org.meanbean.util.Types.getRawType(superType); if ((!classA.isPrimitive()) && (!superClass.isPrimitive())) { return superClass.isAssignableFrom(classA); } return (classA.getSimpleName().equals(classA.getSimpleName())); } private static class UrlEqualityTestWarning { private static final AtomicBoolean printed = new AtomicBoolean(); private static void ifNeeded(EqualityTest equalityTest, Object bean, String propertyName, Object propertyValue) { if (equalityTest != EqualityTest.LOGICAL) { return; } if (propertyValue instanceof URL && !printed.getAndSet(true)) { $Logger logger = $LoggerFactory.getLogger(BeanPropertyTester.class); logger.warn("Bean '{}' has URL property '{}'. Equality tests on URL can be slow. Consider ignoring the property.", bean.getClass().getName(), propertyName); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy