Java tutorial
/* * Copyright 2015 Sharmarke Aden <saden1 at gmail.org>. * * 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 com.fitbur.jestify.junit.spring.injector; import com.fitbur.jestify.api.Mock; import com.fitbur.jestify.core.TestContext; import com.fitbur.jestify.core.TestInjector; import com.fitbur.jestify.core.TestReifier; import com.fitbur.jestify.core.descriptor.DescriptorKey; import com.fitbur.jestify.core.descriptor.FieldDescriptor; import com.fitbur.jestify.core.descriptor.ParameterDescriptor; import static com.google.common.base.Preconditions.checkArgument; import java.lang.reflect.Field; import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.util.Map; import java.util.Optional; import javax.inject.Provider; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.core.ResolvableType; /** * * @author saden1 */ public class NameMockInjector implements TestInjector { private final TestContext context; private final TestReifier testReifier; private final AnnotationConfigApplicationContext applicationContext; private final FieldDescriptor fieldDescriptor; private final Object[] arguments; public NameMockInjector(TestContext context, TestReifier testReifier, AnnotationConfigApplicationContext applicationContext, FieldDescriptor fieldDescriptor, Object[] arguments) { this.context = context; this.testReifier = testReifier; this.applicationContext = applicationContext; this.fieldDescriptor = fieldDescriptor; this.arguments = arguments; } @Override public void inject() { Map<DescriptorKey, ParameterDescriptor> parameterDescriptors = context.getParamaterDescriptors(); Field field = fieldDescriptor.getField(); Type fieldType = field.getGenericType(); Mock mock = fieldDescriptor.getMock().get(); String mockName = mock.name(); DescriptorKey descriptorKey = new DescriptorKey(fieldType, mockName); ParameterDescriptor parameterDescriptor = parameterDescriptors.get(descriptorKey); checkArgument(parameterDescriptor != null, "Can not mock field '%s'. Could not find class under test constructor " + "argument with the name '%s'.", field.getName(), mockName); Parameter parameter = parameterDescriptor.getParameter(); Integer index = parameterDescriptor.getIndex(); Type parameterType = parameter.getParameterizedType(); checkArgument(fieldType.equals(parameterType), "Can not mock field '%s'. Test class field type '%s' and class under test " + "constructor parameter type '%s' with name '%s' do not match.", field.getName(), field.getGenericType(), parameterType, mockName); ResolvableType resolver = ResolvableType.forType(parameterType); Class rawType; if (resolver.hasGenerics()) { if (resolver.isAssignableFrom(Provider.class) || resolver.isAssignableFrom(Optional.class)) { rawType = resolver.getRawClass(); } else { rawType = resolver.resolve(); } } else { rawType = (Class) parameterType; } checkArgument(arguments[index] == null, "Can not mock field '%s'. Multipe test class fields have the same index of '%d'", field.getName(), index); Object instance = testReifier.reifyField(fieldDescriptor, parameterDescriptor); arguments[index] = instance; } }