org.wisepersist.gwtmockito.ng.AbstractGwtTest Maven / Gradle / Ivy
/*
* Copyright (c) 2016 WisePersist.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 org.wisepersist.gwtmockito.ng;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Set;
import static org.mockito.Mockito.mock;
import static org.reflections.ReflectionUtils.getAllFields;
import static org.reflections.ReflectionUtils.withAnnotation;
/**
* Base test for all Gwt unit tests.
*
* @author jiakuanwang
* @param The actual type which is under test.
*/
public abstract class AbstractGwtTest {
private static final Logger log = LoggerFactory.getLogger(AbstractGwtTest.class); //NOPMD
private Injector injector;
/**
* Initialises {@link com.google.gwt.core.client.GWT#create(Class)} with mock objects, and
* inject mock objects into this presenter automatically, before each test method.
*
* @throws Exception If uncaught errors occur.
*/
@BeforeMethod
public final void injectMocks() throws Exception {
GwtMockito.initMocks(this);
this.injector = Guice.createInjector(new TestModule());
initAllFields();
}
/**
* Initialises injected fields value.
*
* @throws IllegalAccessException If illegal access errors occur.
*/
@SuppressWarnings("unchecked")
private void initAllFields() throws IllegalAccessException {
final Set fields = getAllFields(getClass(), withAnnotation(Inject.class));
for (final Field field : fields) {
log.debug("Injecting field with mock object: {} {}",
field.getType().getSimpleName(), field.getName());
final Object fieldValue = getInjected(field.getType());
field.setAccessible(true);
field.set(this, fieldValue);
}
}
/**
* Gets injected mock object.
*
* @param injectedType The injected type class specified.
* @param The injected type.
* @return The injected mock object.
*/
public final E getInjected(final Class injectedType) {
return injector.getInstance(injectedType);
}
/**
* Gets the presenter instance which is being under tests.
*
* @return The presenter instance which is being under tests.
*/
public final T getInstanceUnderTest() {
return injector.getInstance(getClassUnderTest());
}
/**
* Gets presenter class from the generic type of this class.
*
* @return The actual presenter class.
*/
@SuppressWarnings("unchecked")
private Class getClassUnderTest() {
return (Class) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
/**
* Defines presenter module which can automatically inject mock objects into the presenter.
*/
private class TestModule extends AbstractModule {
@Override
protected final void configure() {
bindFieldsWithMocks();
bindConstructorParametersWithMocks();
}
/**
* Binds injected fields with mock instances.
*/
private void bindFieldsWithMocks() {
final Field[] declaredFields = getClassUnderTest().getDeclaredFields();
for (final Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(Inject.class)) {
log.debug("Injecting field with mock object: {} {}",
declaredField.getType().getSimpleName(), declaredField.getName());
bindMockInstance(declaredField.getType());
}
}
}
/**
* Binds injected constructor parameters with mock instances.
*/
private void bindConstructorParametersWithMocks() {
final Constructor>[] constructors = getClassUnderTest().getDeclaredConstructors();
for (final Constructor> constructor : constructors) {
if (constructor.isAnnotationPresent(Inject.class)) {
final Class>[] parameterTypes = constructor.getParameterTypes();
for (final Class> parameterType : parameterTypes) {
log.debug("Injecting constructor arg with mock object: {}",
parameterType.getSimpleName());
bindMockInstance(parameterType);
}
}
}
}
/**
* Binds a the specified type with a mock object in this Guice module.
*
* @param type The type specified.
*/
@SuppressWarnings("unchecked")
private void bindMockInstance(final Class> type) {
final TypeLiteral typeLiteral = TypeLiteral.get(type);
bind(typeLiteral).toInstance(mock(type));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy