001: /* MockableMethodPredicate.java
002: *
003: * DDSteps - Data Driven JUnit Test Steps
004: * Copyright (C) 2005 Jayway AB
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License version 2.1 as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, visit
017: * http://www.opensource.org/licenses/lgpl-license.php
018: */
019: package org.ddsteps.mock;
020:
021: import java.lang.reflect.Method;
022:
023: import org.apache.commons.collections.Predicate;
024: import org.apache.commons.lang.Validate;
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027:
028: /**
029: * Predicate for sifting out methods that should not be mocked.
030: * <p>
031: * Methods that never should be mocked are equals, toString and hashCode, both those in Object and any overrides. Also,
032: * final methods cannot be mocked, so warn and omit them. Also, native methods.
033: * </p>
034: *
035: * @author adam
036: * @version $Id: MockableMethodPredicate.java,v 1.1 2005/12/03 12:51:40 adamskogman Exp $
037: */
038: class MockableMethodPredicate implements Predicate {
039:
040: protected static Method equalsMethod;
041:
042: protected static Method hashCodeMethod;
043:
044: protected static Method toStringMethod;
045:
046: private static final Log LOG = LogFactory
047: .getLog(MockableMethodPredicate.class);
048:
049: static {
050:
051: try {
052: equalsMethod = Object.class.getMethod("equals",
053: new Class[] { Object.class });
054: hashCodeMethod = Object.class.getMethod("hashCode",
055: new Class[0]);
056: toStringMethod = Object.class.getMethod("toString",
057: new Class[0]);
058: } catch (NoSuchMethodException e) {
059: LOG
060: .fatal(
061: "An Object method could not be found! You have serious issues, dude!",
062: e);
063: }
064:
065: }
066:
067: /**
068: * Dependecy: Reflection Utils
069: */
070: protected final ReflectionUtils reflectionUtils;
071:
072: /**
073: * DI constructor.
074: *
075: * @param reflectionUtils
076: */
077: public MockableMethodPredicate(ReflectionUtils reflectionUtils) {
078: super ();
079: this .reflectionUtils = reflectionUtils;
080: }
081:
082: /**
083: * Returns true if the method should be mocked.
084: *
085: * @see org.apache.commons.collections.Predicate#evaluate(java.lang.Object)
086: */
087: public boolean evaluate(Object object) {
088:
089: Validate.notNull(object, "Argument object must not be null");
090: Validate.isTrue(object instanceof Method,
091: "Argument object must be a type");
092:
093: Method method = (Method) object;
094:
095: // warn if final
096: if (reflectionUtils.isFinal(method)) {
097:
098: if (method.getClass() == Object.class) {
099: // Don't shout if it is final in Object
100: if (LOG.isDebugEnabled()) {
101: LOG
102: .debug("Final method from Object, cannot be mocked. (Method = "
103: + method + ")");
104: }
105: } else {
106: LOG.warn("Final method, cannot be mocked. (Method = "
107: + method + ")");
108: }
109: return false;
110: }
111:
112: // Any overriden versions of equals, toString and hashCode
113: if (reflectionUtils.isOverride(method, equalsMethod)) {
114: if (LOG.isDebugEnabled()) {
115: LOG.debug("Not mocking equals() method. (Method = "
116: + method + ")");
117: }
118: return false;
119: }
120: if (reflectionUtils.isOverride(method, toStringMethod)) {
121: if (LOG.isDebugEnabled()) {
122: LOG.debug("Not mocking toString() method. (Method = "
123: + method + ")");
124: }
125: return false;
126: }
127: if (reflectionUtils.isOverride(method, hashCodeMethod)) {
128: if (LOG.isDebugEnabled()) {
129: LOG.debug("Not mocking hashCode() method. (Method = "
130: + method + ")");
131: }
132: return false;
133: }
134:
135: if (LOG.isDebugEnabled()) {
136: LOG.debug("Method is mockable. (Method = " + method + ")");
137: }
138:
139: return true;
140:
141: }
142:
143: }
|