package com.vtence.molecule.middlewares; import com.vtence.molecule.Request; import com.vtence.molecule.Response; import org.jmock.Expectations; import org.jmock.States; import org.jmock.integration.junit4.JUnitRuleMockery; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import javax.sql.DataSource; import java.sql.Connection; import java.util.concurrent.ExecutionException; import static com.vtence.molecule.testing.RequestAssert.assertThat; import static com.vtence.molecule.testing.ResponseAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; public class ConnectionScopeTest { @Rule public JUnitRuleMockery context = new JUnitRuleMockery(); DataSource dataSource = context.mock(DataSource.class); ConnectionScope connectionScope = new ConnectionScope(dataSource); Connection connection = context.mock(Connection.class); States connectionStatus = context.states("connection").startsAs("closed"); Request request = new Request(); Response response = new Response(); @Rule public ExpectedException error = ExpectedException.none(); @Before public void expectConnectionToBeReleasedAfterwards() throws Exception { context.checking(new Expectations() {{ allowing(dataSource).getConnection(); will(returnValue(connection)); when(connectionStatus.is("closed")); then(connectionStatus.is("opened")); oneOf(connection).close(); when(connectionStatus.is("opened")); then(connectionStatus.is("closed")); }}); } @Test public void opensConnectionAndMakesItAvailableAsRequestAttribute() throws Exception { connectionScope.connectTo((request, response) -> response.body(request.attribute(Connection.class) == connection ? "opened" : "closed")); connectionScope.handle(request, response); response.done(); assertNoExecutionError(); assertThat(response).hasBodyText("opened"); } @Test public void removesConnectionFromScopeAfterUse() throws Exception { connectionScope.handle(request, response); assertThat(request).hasAttribute(Connection.class, notNullValue()); response.done(); assertNoExecutionError(); assertThat(request).hasNoAttribute(Connection.class); } @Test public void gracefullyClosesConnectionWhenAnErrorOccurs() throws Exception { connectionScope.connectTo((request, response) -> { throw new Exception("Boom!"); }); error.expectMessage("Boom!"); try { connectionScope.handle(request, response); } finally { assertThat(request).hasNoAttribute(Connection.class); } } @Test public void gracefullyClosesConnectionWhenAnErrorOccursLater() throws Throwable { connectionScope.handle(request, response); assertThat(request).hasAttribute(Connection.class, notNullValue()); response.done(new Exception("Boom!")); assertThat(request).hasNoAttribute(Connection.class); } private void assertNoExecutionError() throws ExecutionException, InterruptedException { response.await(); } }