package net.kencochrane.raven.connection;

import mockit.*;
import net.kencochrane.raven.Raven;
import net.kencochrane.raven.event.Event;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class AsyncConnectionTest {
    private AsyncConnection asyncConnection;
    @Injectable
    private Connection mockConnection;
    @Injectable
    private ExecutorService mockExecutorService;
    @Mocked("addShutdownHook")
    private Runtime mockRuntime;

    @BeforeMethod
    public void setUp() throws Exception {
        asyncConnection = new AsyncConnection(mockConnection);
        asyncConnection.setExecutorService(mockExecutorService);
    }

    @Test
    public void verifyShutdownHookIsAdded() throws Exception {
        new AsyncConnection(mockConnection);

        new Verifications() {{
            mockRuntime.addShutdownHook((Thread) any);
        }};
    }

    @Test
    public void verifyShutdownHookClosesConnection() throws Exception {
        new NonStrictExpectations() {{
            mockRuntime.addShutdownHook((Thread) any);
            result = new Delegate<Void>() {
                public void addShutdownHook(Thread thread) {
                    thread.run();
                }
            };
        }};

        new AsyncConnection(mockConnection);

        new Verifications() {{
            mockConnection.close();
        }};
    }

    @Test
    public void verifyShutdownHookSetRavenManagedThreadFlag(
            @Mocked({"manageThread", "stopManagingThread"}) Raven mockRaven) throws Exception {
        new NonStrictExpectations() {{
            mockRuntime.addShutdownHook((Thread) any);
            result = new Delegate<Void>() {
                public void addShutdownHook(Thread thread) {
                    thread.run();
                }
            };
        }};

        new AsyncConnection(mockConnection);

        new Verifications() {{
            Raven.manageThread();
            Raven.stopManagingThread();
        }};
    }

    @Test
    public void testCloseOperation() throws Exception {
        asyncConnection.close();

        new Verifications() {{
            mockConnection.close();
            mockExecutorService.awaitTermination(anyLong, (TimeUnit) any);
        }};
    }

    @Test
    public void testSendEventQueued(@Injectable final Event mockEvent) throws Exception {
        asyncConnection.send(mockEvent);

        new Verifications() {{
            mockExecutorService.execute((Runnable) any);
        }};
    }

    @Test
    public void testQueuedEventExecuted(@Injectable final Event mockEvent) throws Exception {
        new Expectations() {{
            mockExecutorService.execute((Runnable) any);
            result = new Delegate() {
                public void execute(Runnable runnable) {
                    runnable.run();
                }
            };
        }};

        asyncConnection.send(mockEvent);

        new Verifications() {{
            mockConnection.send(mockEvent);
        }};
    }
}

@@ -1029,526 +1029,43 @@
 Hook
-ClosesConnection() throws Exception %7B%0A        new NonStrictExpectations() %7B%7B%0A            mockRuntime.addShutdownHook((Thread) any);%0A            result = new Delegate%3CVoid%3E() %7B%0A                public void addShutdownHook(Thread thread) %7B%0A                    thread.run();%0A                %7D%0A            %7D;%0A        %7D%7D;%0A%0A        new AsyncConnection(mockConnection);%0A%0A        new Verifications() %7B%7B%0A            mockConnection.close();%0A        %7D%7D;%0A    %7D%0A%0A    @Test%0A    public void verifyShutdownHookSetRavenManagedThreadFlag
+SetManagedByRavenAndCloseConnection
 (%0A  
@@ -1500,32 +1500,39 @@
 ew Verifications
+InOrder
 () %7B%7B%0A          
@@ -1547,32 +1547,68 @@
 manageThread();%0A
+            mockConnection.close();%0A
             Rave

Check thread managemnt and connection close in the same test