/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * 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 * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.List; import static com.google.common.collect.Lists.newArrayList; import static org.junit.Assert.assertTrue; public class AnnotatedLifecycleMethodStrategyTest { static final List<String> callAssertion = new ArrayList<>(); public static class WithLifeCycleAnnotation { @PostConstruct public void init() { callAssertion.add("init"); } @PostConstruct private void nonPublicInit() { callAssertion.add("nonPublicInit"); } @PostConstruct public static void staticInit() { callAssertion.add("staticInit"); } @PostConstruct public void initWithParams(String str) { callAssertion.add("initWithParams"); } @PostConstruct public void initThatThrowsCheckedException() throws Exception { callAssertion.add("initThatThrowsCheckedException"); } @PreDestroy public void destroy() { callAssertion.add("destroy"); } @PreDestroy private void nonPublicdestroy() { callAssertion.add("nonPublicDestroy"); } @PreDestroy public static void staticDestroy() { callAssertion.add("staticDestroy"); } @PreDestroy public void destroyWithParams(String str) { callAssertion.add("destroyWithParams"); } @PreDestroy public void destroyThatThrowsCheckedException() throws Exception { callAssertion.add("destroyThatThrowsCheckedException"); } } @Rule public ExpectedException thrown = ExpectedException.none(); private AnnotatedLifecycleMethodStrategy lifecycleMethodStrategy; @Before public void setUp() throws Exception { lifecycleMethodStrategy = new AnnotatedLifecycleMethodStrategy(); } @After public void tearDown() throws Exception { callAssertion.clear(); } @Test public void invokesInitializeMethods() throws Exception { lifecycleMethodStrategy.invokeInitializeMethods(new WithLifeCycleAnnotation()); assertTrue(String.format("Only \"init\" and \"nonPublicInit\" methods are expected to be invoked but %s were invoked", callAssertion), callAssertion.size() == 2 && callAssertion.containsAll(newArrayList("init", "nonPublicInit"))); } @Test public void invokesDestroyMethods() throws Exception { lifecycleMethodStrategy.invokeDestroyMethods(new WithLifeCycleAnnotation()); assertTrue(String.format("Only \"destroy\" and \"nonPublicDestroy\" methods are expected to be invoked but %s were invoked", callAssertion), callAssertion.size() == 2 && callAssertion.containsAll(newArrayList("destroy", "nonPublicDestroy"))); } public static class LifeCycleMethodsThrowsRuntimeException { @PostConstruct public void init() { throw new RuntimeException("init fails"); } @PreDestroy public void destroy() { throw new RuntimeException("destroy fails"); } } @Test public void wrapsRuntimeExceptionThrownByInitMethodWithInternalException() { thrown.expect(lifecycleMethodInvocationExceptionMatcher("init fails")); lifecycleMethodStrategy.invokeInitializeMethods(new LifeCycleMethodsThrowsRuntimeException()); } @Test public void wrapsRuntimeExceptionThrownByDestroyMethodWithInternalException() { thrown.expect(lifecycleMethodInvocationExceptionMatcher("destroy fails")); lifecycleMethodStrategy.invokeDestroyMethods(new LifeCycleMethodsThrowsRuntimeException()); } private BaseMatcher<Throwable> lifecycleMethodInvocationExceptionMatcher(String expectedMessage) { return new BaseMatcher<Throwable>() { @Override public boolean matches(Object item) { return item instanceof InternalException && ((InternalException) item).getCause() instanceof RuntimeException && expectedMessage.equals(((InternalException) item).getCause().getMessage()); } @Override public void describeTo(Description description) { description.appendText(String.format("Expected exception with message: %s", expectedMessage)); } }; } }