shiver.me.timbers.waiting.WaiterAspectTest.java Source code

Java tutorial

Introduction

Here is the source code for shiver.me.timbers.waiting.WaiterAspectTest.java

Source

/*
 * Copyright 2015 Karl Bennett
 *
 * 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 shiver.me.timbers.waiting;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static shiver.me.timbers.data.random.RandomStrings.someString;

@SuppressWarnings("unchecked")
public class WaiterAspectTest {

    private ServiceLoader<WaiterService, OptionsService> waiterLoader;
    private ServiceLoader<OptionsService, Wait> optionsLoader;
    private WaiterAspect aspect;

    @Before
    public void setUp() {
        waiterLoader = mock(ServiceLoader.class);
        optionsLoader = mock(ServiceLoader.class);
        aspect = new WaiterAspect(waiterLoader, optionsLoader);
    }

    @Test
    public void Can_create_a_waiter_aspect() {
        new WaiterAspect();
    }

    @Test
    public void Call_isMethod_for_100_percent_coverage()
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        final Method isMethod = WaiterAspect.class.getDeclaredMethod("isMethod");
        isMethod.setAccessible(true);
        isMethod.invoke(aspect);
    }

    @Test
    public void Can_wait_for_method_in_class() throws Throwable {

        final ProceedingJoinPoint joinPoint = mock(ProceedingJoinPoint.class);
        final Wait wait = mock(Wait.class);

        final WaiterService waiterService = mock(WaiterService.class);
        final OptionsService options = mock(OptionsService.class);

        final Signature signature = mock(Signature.class);
        final String[] toString = new String[1];
        final Object[] success = new Object[1];
        final Object expected = new Object();

        // Given
        given(joinPoint.getSignature()).willReturn(signature);
        given(signature.getDeclaringType()).willReturn(Object.class);
        given(signature.getName()).willReturn(someString());
        given(optionsLoader.load(wait)).willReturn(options);
        given(waiterLoader.load(options)).willReturn(waiterService);
        willAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                final Until until = (Until) invocation.getArguments()[0];
                toString[0] = until.toString();
                return success[0] = until.success();
            }
        }).given(waiterService).wait(any(Until.class));
        given(joinPoint.proceed()).willReturn(expected);

        // When
        final Object actual = aspect.waitOnClass(joinPoint, wait);

        // Then
        assertThat(actual, is(success[0]));
        assertThat(actual, is(expected));
        assertThat(joinPoint.toString(), is(toString[0]));
    }

    @Test
    public void Can_wait_for_method() throws Throwable {

        final ProceedingJoinPoint joinPoint = mock(ProceedingJoinPoint.class);
        final Wait wait = mock(Wait.class);

        final WaiterService waiterService = mock(WaiterService.class);
        final OptionsService options = mock(OptionsService.class);

        final String[] toString = new String[1];
        final Object[] success = new Object[1];
        final Object expected = new Object();

        // Given
        given(optionsLoader.load(wait)).willReturn(options);
        given(waiterLoader.load(options)).willReturn(waiterService);
        willAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                final Until until = (Until) invocation.getArguments()[0];
                toString[0] = until.toString();
                return success[0] = until.success();
            }
        }).given(waiterService).wait(any(Until.class));
        given(joinPoint.proceed()).willReturn(expected);

        // When
        final Object actual = aspect.waitOnMethod(joinPoint, wait);

        // Then
        assertThat(actual, is(success[0]));
        assertThat(actual, is(expected));
        assertThat(joinPoint.toString(), is(toString[0]));
    }

    @Test
    public void A_new_waiter_is_loaded_every_time() throws Throwable {

        final ProceedingJoinPoint joinPoint = mock(ProceedingJoinPoint.class);
        final Wait wait = mock(Wait.class);

        final Signature signature = mock(Signature.class);
        final WaiterService waiterService = mock(WaiterService.class);
        final OptionsService options = mock(OptionsService.class);

        // Given
        given(joinPoint.getSignature()).willReturn(signature);
        given(signature.getDeclaringType()).willReturn(Object.class);
        given(signature.getName()).willReturn(someString());
        given(optionsLoader.load(wait)).willReturn(options);
        given(waiterLoader.load(options)).willReturn(waiterService);

        // When
        aspect.waitOnClass(joinPoint, wait);
        aspect.waitOnMethod(joinPoint, wait);
        aspect.waitOnClass(joinPoint, wait);

        // Then
        verify(optionsLoader, times(3)).load(wait);
        verify(waiterLoader, times(3)).load(options);
        verify(waiterService, times(3)).wait(any(Until.class));
    }

    @Test
    public void Will_ignore_class_annotation_if_method_is_annotated() throws Throwable {

        final ProceedingJoinPoint joinPoint = mock(ProceedingJoinPoint.class);
        final Wait wait = mock(Wait.class);

        final Signature signature = mock(Signature.class);
        @Wait
        class WaitMethodOverride {
            @Wait
            private void overrideWaitMethod() {
            }
        }

        final Object expected = new Object();

        // Given
        given(joinPoint.getSignature()).willReturn(signature);
        given(signature.getDeclaringType()).willReturn(WaitMethodOverride.class);
        given(signature.getName()).willReturn("overrideWaitMethod");
        given(joinPoint.proceed()).willReturn(expected);

        // When
        final Object actual = aspect.waitOnClass(joinPoint, wait);

        // Then
        assertThat(actual, is(expected));
        verifyZeroInteractions(optionsLoader, waiterLoader);
    }
}