diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/JUnit5TestableFactory.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/JUnit5TestableFactory.java index f9d3e392f97..033c973d7df 100644 --- a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/JUnit5TestableFactory.java +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/JUnit5TestableFactory.java @@ -16,6 +16,7 @@ import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -115,33 +116,8 @@ private JUnit5Testable createTestable(UniqueId uniqueId, UniqueId engineId, List } private Method findMethod(String methodSpecPart, Class clazz, UniqueId uniqueId) { - // TODO Throw IAE when format wrong. Currently you get IndexOutOfBoundsException. - int startParams = methodSpecPart.indexOf('('); - String methodName = methodSpecPart.substring(0, startParams); - int endParams = methodSpecPart.lastIndexOf(')'); - String paramsPart = methodSpecPart.substring(startParams + 1, endParams); - Class[] parameterTypes = resolveParameterTypes(paramsPart, uniqueId); - return findMethod(clazz, methodName, parameterTypes); - } - - private Class[] resolveParameterTypes(String paramsPart, UniqueId uniqueId) { - if (paramsPart.isEmpty()) { - return new Class[0]; - } - - // @formatter:off - List> types = Arrays.stream(paramsPart.split(",")) - .map(className -> loadRequiredParamterClass(className, uniqueId, paramsPart)) - .collect(Collectors.toList()); - // @formatter:on - - return types.toArray(new Class[types.size()]); - } - - private Method findMethod(Class clazz, String methodName, Class[] parameterTypes) { - return ReflectionUtils.findMethod(clazz, methodName, parameterTypes).orElseThrow( - () -> new PreconditionViolationException(String.format("No method with name '%s' and parameter types '%s'", - methodName, StringUtils.nullSafeToString(parameterTypes)))); + Optional optionalMethod = new MethodFinder().findMethod(methodSpecPart, clazz); + return optionalMethod.orElseThrow(() -> createCannotResolveUniqueIdException(uniqueId, methodSpecPart)); } private Class findNestedClass(String nameExtension, Class containerClass) { @@ -162,11 +138,6 @@ private Class loadClassByName(String className) { () -> new PreconditionViolationException(String.format("Cannot load class '%s'", className))); } - private Class loadRequiredParamterClass(String className, UniqueId fullUniqueId, String paramsPart) { - return ReflectionUtils.loadClass(className).orElseThrow( - () -> createCannotResolveUniqueIdException(fullUniqueId, paramsPart)); - } - private static RuntimeException createCannotResolveUniqueIdException(UniqueId fullUniqueId, String uniqueIdPart) { return new PreconditionViolationException( String.format("Cannot resolve part '%s' of unique ID '%s'", uniqueIdPart, fullUniqueId.getUniqueString())); diff --git a/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/MethodFinder.java b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/MethodFinder.java new file mode 100644 index 00000000000..f25f466fbe4 --- /dev/null +++ b/junit5-engine/src/main/java/org/junit/gen5/engine/junit5/discovery/MethodFinder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015-2016 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v10.html + */ + +package org.junit.gen5.engine.junit5.discovery; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.junit.gen5.commons.util.PreconditionViolationException; +import org.junit.gen5.commons.util.ReflectionUtils; +import org.junit.gen5.engine.UniqueId; + +public class MethodFinder { + + public Optional findMethod(String methodSpecPart, Class clazz) { + try { + + // TODO Throw IAE when format wrong. Currently you get IndexOutOfBoundsException. + int startParams = methodSpecPart.indexOf('('); + String methodName = methodSpecPart.substring(0, startParams); + int endParams = methodSpecPart.lastIndexOf(')'); + String paramsPart = methodSpecPart.substring(startParams + 1, endParams); + Class[] parameterTypes = resolveParameterTypes(paramsPart); + return findMethod(clazz, methodName, parameterTypes); + } + catch (RuntimeException rte) { + return Optional.empty(); + } + } + + private Class[] resolveParameterTypes(String paramsPart) { + if (paramsPart.isEmpty()) { + return new Class[0]; + } + + // @formatter:off + List> types = Arrays.stream(paramsPart.split(",")) + .map(className -> loadRequiredParameterClass(className)) + .collect(Collectors.toList()); + // @formatter:on + + return types.toArray(new Class[types.size()]); + } + + private Optional findMethod(Class clazz, String methodName, Class[] parameterTypes) { + return ReflectionUtils.findMethod(clazz, methodName, parameterTypes); + } + + private Class loadRequiredParameterClass(String className) { + return ReflectionUtils.loadClass(className).orElseThrow(() -> new RuntimeException("Not found: " + className)); + } + + private static RuntimeException createCannotResolveUniqueIdException(UniqueId fullUniqueId, String uniqueIdPart) { + return new PreconditionViolationException( + String.format("Cannot resolve part '%s' of unique ID '%s'", uniqueIdPart, fullUniqueId.getUniqueString())); + } + +}