public JavassistMockClassLoader(String[] classesToMock, String[] packagesToDefer, UseClassPathAdjuster useClassPathAdjuster) { this(new MockClassLoaderConfiguration(classesToMock, packagesToDefer), useClassPathAdjuster); }
/** * Create an instance of configuration * @param classesToMock classes that should be modified by {@link MockClassLoader}. * @param packagesToDefer classes/packages that should be deferred to system class loader. */ public MockClassLoaderConfiguration(String[] classesToMock, String[] packagesToDefer) { deferPackages = getPackagesToDefer(packagesToDefer); addClassesToModify(classesToMock); }
private boolean shouldDefer(String[] packages, String name) { for (String packageToCheck : packages) { if (deferConditionMatches(name, packageToCheck)) { return true; } } return false; }
boolean shouldMockClass(String className) { return shouldModify(className) && !shouldLoadWithMockClassloaderWithoutModifications(className); }
boolean shouldModify(String className) { final boolean shouldIgnoreClass = shouldIgnore(className); final boolean shouldModifyAll = shouldModifyAll(); if (shouldModifyAll) { return !shouldIgnoreClass; } else { /* * Never mind if we should ignore the class here since * classes added by prepared for test should (i.e. those added in "modify") * have precedence over ignored packages. */ return WildcardMatcher.matchesAny(modify, className); } }
private boolean deferConditionMatches(String name, String packageName) { final boolean wildcardMatch = WildcardMatcher.matches(name, packageName); return wildcardMatch && !(shouldLoadUnmodifiedClass(name) || shouldModifyClass(name)); }
boolean shouldDefer(String className) { return shouldDefer(deferPackages, className); }
private boolean shouldIgnore(String className) { return shouldIgnore(deferPackages, className); }
private void updateClassLoaderConfiguration(MockClassLoaderConfiguration configuration) { MockPolicyClassLoadingSettings classLoadingSettings = getClassLoadingSettings(); String[] fullyQualifiedNamesOfClassesToLoadByMockClassloader = classLoadingSettings.getFullyQualifiedNamesOfClassesToLoadByMockClassloader(); configuration.addClassesToModify(fullyQualifiedNamesOfClassesToLoadByMockClassloader); if (testClass == null) { throw new IllegalStateException("Internal error: testClass should never be null when calling initialize on a mock policy"); } configuration.addClassesToModify(testClass.getName()); Class<?>[] classes = testClass.getDeclaredClasses(); for (Class<?> clazz : classes) { configuration.addClassesToModify(clazz.getName()); } Class<?>[] declaredClasses = testClass.getClasses(); for (Class<?> clazz : declaredClasses) { configuration.addClassesToModify(clazz.getName()); } for (String string : classLoadingSettings.getStaticInitializersToSuppress()) { configuration.addClassesToModify(string); MockRepository.addSuppressStaticInitializer(string); } }
@Override protected Class<?> loadClassByThisClassLoader(String className) throws ClassFormatError, ClassNotFoundException { final Class<?> loadedClass; Class<?> deferClass = deferTo.loadClass(className); if (getConfiguration().shouldMockClass(className)) { loadedClass = loadMockClass(className, deferClass.getProtectionDomain()); } else { loadedClass = loadUnmockedClass(className, deferClass.getProtectionDomain()); } return loadedClass; }
private boolean shouldDefer(String name) { return configuration.shouldDefer(name); }
/** * Creates a new instance of the based on the * following parameters: * * @param classesToMock The classes that must be modified to prepare for testability. * @param packagesToDefer Classes in these packages will be defered to the system * class-loader. */ protected MockClassLoader(String[] classesToMock, String[] packagesToDefer) { this(new MockClassLoaderConfiguration(classesToMock, packagesToDefer), new JavaAssistClassWrapperFactory()); }
/** * Add classes that will be loaded by the mock classloader, i.e. these * classes will be byte-code manipulated to allow for testing. Any classes * contained in the {@link #PACKAGES_TO_BE_DEFERRED} will be ignored. How ever * classes added here have precedence over additionally deferred (ignored) * packages (those ignored by the user using @PrepareForTest). * * @param classes The fully qualified name of the classes that will be appended * to the list of classes that will be byte-code modified to * enable testability. */ public final void addClassesToModify(String... classes) { if (classes != null) { for (String clazz : classes) { if (!shouldDefer(PACKAGES_TO_BE_DEFERRED, clazz)) { modify.add(clazz); } } } }
public MockClassLoader build() { internalAssertNotNull(testClass, "Test class is null during building classloader. "); final MockClassLoaderConfiguration configuration = new MockClassLoaderConfiguration(classesToModify, packagesToIgnore); final MockClassLoader classLoader = byteCodeFramework.createClassloader(configuration, useClassPathAdjuster); classLoader.setMockTransformerChain(createTransformerChain()); return classLoader; }