/** * Copyright (C) 2010 hprange <hprange@gmail.com> * * 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.webobjects.foundation; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.internal.util.MockUtil; import org.mockito.runners.MockitoJUnitRunner; import com.google.inject.AbstractModule; import com.google.inject.Module; import com.google.inject.matcher.Matchers; import com.google.inject.name.Names; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.woinject.AbstractInjectableTestCase; import com.woinject.WOInjectException; import com.woinject.stubs.StubApplication; import com.woinject.stubs.StubComponent; import com.woinject.stubs.StubDirectAction; import com.woinject.stubs.StubEnterpriseObject; import com.woinject.stubs.StubObject; import com.woinject.stubs.StubSession; /** * @author <a href="mailto:hprange@gmail.com.br">Henrique Prange</a> */ @RunWith(MockitoJUnitRunner.class) public class TestInstantiationInterceptor extends AbstractInjectableTestCase { private static class StubInterceptor implements MethodInterceptor { int invocations = 0; public Object invoke(MethodInvocation invocation) throws Throwable { invocations++; return invocation.proceed(); } public void reset() { invocations = 0; } } private static class StubModule extends AbstractModule { private final MethodInterceptor interceptor; public StubModule(MethodInterceptor interceptor) { this.interceptor = interceptor; } @Override protected void configure() { bind(String.class).annotatedWith(Names.named("test")).toInstance("expectedText"); bind(StubObjectForBinding.class).toInstance(mock(StubObjectForBinding.class)); bindInterceptor(Matchers.any(), Matchers.any(), interceptor); } } static class StubObjectForBinding { public StubObjectForBinding() { } } private StubInterceptor interceptor; @Mock private WOContext mockContext; @Mock private WORequest mockRequest; private Object[][] parameters; @Rule public final ExpectedException thrown = ExpectedException.none(); @Test public void bindInterceptorToSpecialObjectsWithConstructorUsingGuice() throws Throwable { for (Object[] parameter : parameters) { @SuppressWarnings("unchecked") Object result = InstantiationInterceptor.instantiateObject((Constructor<Object>) parameter[3], (Class<Object>) parameter[0], (Object[]) parameter[2], true, false); interceptor.reset(); result.toString(); assertThat(interceptor.invocations, is(1)); } } @Test public void bindInterceptorToSpecialObjectsWithGuice() throws Throwable { for (Object[] parameter : parameters) { Object result = InstantiationInterceptor.instantiateObject((Class<?>) parameter[0], (Class<?>[]) parameter[1], (Object[]) parameter[2], true, false); interceptor.reset(); result.toString(); assertThat(interceptor.invocations, is(1)); } } @Test public void doNotThrowExceptionIfNotRequired() throws Exception { try { InstantiationInterceptor.instantiateObject(StubComponent.class, new Class<?>[] { WOContext.class }, new Object[] { mockRequest }, false, true); InstantiationInterceptor.instantiateObject(StubObject.class, new Class<?>[] { String.class, String.class }, null, false, true); InstantiationInterceptor.instantiateObject(StubObject.class, null, null, false, true); } catch (Exception exception) { exception.printStackTrace(); fail("Should not throw an exception"); } } @Test public void injectOrdinaryObjectMembersAfterConstructionWithReflection() throws Exception { Object result = InstantiationInterceptor.instantiateObject(StubObject.class, new Class<?>[] { String.class, String.class }, new Object[] { "teste", "teste2" }, true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf(StubObject.class)); assertThat(result.toString(), is("expectedText")); } @Test public void injectOrdinaryObjectMembersAfterConstructionWithReflectionUsingConstructor() throws Exception { Constructor<StubObject> constructor = StubObject.class.getConstructor(new Class<?>[] { String.class, String.class }); Object result = InstantiationInterceptor.instantiateObject(constructor, StubObject.class, new Object[] { "teste", "teste2" }, true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf(StubObject.class)); assertThat(result.toString(), is("expectedText")); } @Test public void injectSpecialObjectsWithConstructorUsingGuice() throws Exception { for (Object[] parameter : parameters) { @SuppressWarnings("unchecked") Object result = InstantiationInterceptor.instantiateObject((Constructor<Object>) parameter[3], (Class<Object>) parameter[0], (Object[]) parameter[2], true, false); assertThat(result.toString(), is("expectedText")); } } @Test public void injectSpecialObjectsWithGuice() throws Exception { for (Object[] parameter : parameters) { Object result = InstantiationInterceptor.instantiateObject((Class<?>) parameter[0], (Class<?>[]) parameter[1], (Object[]) parameter[2], true, false); assertThat(result.toString(), is("expectedText")); } } @Test public void instantiateObjectWithContructorUsingReflectionIfInjectorIsNull() throws Exception { application.setReturnNullInjector(true); Constructor<StubEnterpriseObject> constructor = StubEnterpriseObject.class.getConstructor(); StubEnterpriseObject result = InstantiationInterceptor.instantiateObject(constructor, StubEnterpriseObject.class, null, true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf(StubEnterpriseObject.class)); } @Test public void instantiateObjectWithReflectionIfApplicationIsNull() throws Exception { StubApplication.setApplication(null); StubEnterpriseObject result = InstantiationInterceptor.instantiateObject(StubEnterpriseObject.class, null, null, true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf(StubEnterpriseObject.class)); } @Test public void instantiateObjectWithReflectionIfInjectorIsNull() throws Exception { application.setReturnNullInjector(true); StubEnterpriseObject result = InstantiationInterceptor.instantiateObject(StubEnterpriseObject.class, null, null, true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf(StubEnterpriseObject.class)); } @Test public void instantiateSpecialObjectsWithConstructorUsingGuice() throws Exception { for (Object[] parameter : parameters) { @SuppressWarnings("unchecked") Object result = InstantiationInterceptor.instantiateObject((Constructor<Object>) parameter[3], (Class<Object>) parameter[0], (Object[]) parameter[2], true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf((Class<?>) parameter[0])); } } @Test public void instantiateSpecialObjectsWithGuice() throws Exception { for (Object[] parameter : parameters) { Object result = InstantiationInterceptor.instantiateObject((Class<?>) parameter[0], (Class<?>[]) parameter[1], (Object[]) parameter[2], true, false); assertThat(result, notNullValue()); assertThat(result, instanceOf((Class<?>) parameter[0])); } } @Override @Before public void setup() throws Exception { final StubInterceptor interceptor = new StubInterceptor(); this.interceptor = interceptor; application = new StubApplication() { @Override protected Module[] modules() { List<Module> modules = new ArrayList<Module>(Arrays.asList(super.modules())); modules.add(new StubModule(interceptor)); return modules.toArray(new Module[modules.size()]); } }; parameters = new Object[][] { { StubEnterpriseObject.class, null, null, StubEnterpriseObject.class.getConstructor() }, { StubComponent.class, new Class<?>[] { WOContext.class }, new Object[] { mockContext }, StubComponent.class.getConstructor(new Class<?>[] { WOContext.class }) }, { StubSession.class, null, null, StubSession.class.getConstructor() }, { StubDirectAction.class, new Class<?>[] { WORequest.class }, new Object[] { mockRequest }, StubDirectAction.class.getConstructor(new Class<?>[] { WORequest.class }) } }; } @Test public void throwExceptionIfGuiceUnableToCreateInstance() throws Exception { thrown.expect(WOInjectException.class); thrown.expectMessage(is("The instantiation of com.woinject.stubs.StubComponent class has failed.")); WORequest illegalArgument = mockRequest; InstantiationInterceptor.instantiateObject(StubComponent.class, new Class<?>[] { WOContext.class }, new Object[] { illegalArgument }, true, false); } @Test public void throwExceptionIfIllegalArguments() throws Exception { thrown.expect(WOInjectException.class); thrown.expectMessage(is("The instantiation of com.woinject.stubs.StubObject class has failed.")); InstantiationInterceptor.instantiateObject(StubObject.class, new Class<?>[] { String.class, String.class }, null, true, false); } @Test public void throwExceptionIfNoSuitableConstructorFound() throws Exception { thrown.expect(WOInjectException.class); thrown.expectMessage(is("The instantiation of com.woinject.stubs.StubObject class has failed.")); InstantiationInterceptor.instantiateObject(StubObject.class, null, null, true, false); } @Test public void useSpecialKeyToAvoidBindingConflictsWithParentInjector() throws Exception { StubObjectForBinding result = InstantiationInterceptor.instantiateObject(StubObjectForBinding.class, null, null, false, false); assertThat(new MockUtil().isMock(result), is(false)); } }