Junit 5 InvocationInterceptor игнорирует метод тестирования - PullRequest
0 голосов
/ 10 ноября 2019

С помощью JUnit 5.5 мы получаем возможность определить InvocationInterceptors , чтобы получить больший контроль над действиями, выполняемыми на различных этапах жизненного цикла теста.

Поэтому я создал этот перехватчик для заменыJUnit 4 подходит с правилами для запуска потоков пользовательского интерфейса и выполнения в них метода теста:

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;

import javax.swing.*;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

public class JavaFxInterceptor implements InvocationInterceptor {

    @Override
    public void interceptBeforeAllMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
        long timeMillis = System.currentTimeMillis();

        final CountDownLatch latch = new CountDownLatch(1);

        SwingUtilities.invokeLater(() -> {
            // initializes JavaFX environment
            new JFXPanel();

            latch.countDown();
        });

        System.out.println("javafx initialising...");
        latch.await();
        System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
    }

    @Override
    public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
        AtomicReference<Throwable> throwable = new AtomicReference<>();

        Platform.runLater(() -> {
            try {
                invocation.proceed();
            }
            catch (Throwable t) {
                throwable.set(t);
            }
        });

        Throwable t = throwable.get();
        if (t != null) {
            throw t;
        }
    }

}

, а затем адаптирует существующий тест для запуска с этой новой функцией:

import ch.sahits.game.graphic.image.impl.SelectiveCachableXMLImageLoader;
import ch.sahits.game.openpatrician.model.IHumanPlayer;
import ch.sahits.game.openpatrician.model.player.EPlayerColor;
import ch.sahits.game.openpatrician.model.ship.EShipType;
import ch.sahits.game.openpatrician.model.ship.IShip;
import ch.sahits.game.openpatrician.testutilities.JavaFxInterceptor;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Point2D;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;

@ExtendWith(JavaFxInterceptor.class)
public class ShipIconTest {
    @BeforeAll
    private static  void initJAvaFX() {

    }
    @Test
    public void shouldUpdateShipPositionInitialisation() {
        // Given
        IShip vessel = mock(IShip.class);
        IHumanPlayer player = mock(IHumanPlayer.class);
        SelectiveCachableXMLImageLoader imageLoader = new SelectiveCachableXMLImageLoader("imageDefinitions.xml");
        Jaxb2Marshaller bean = new Jaxb2Marshaller();
        bean.setContextPath("ch.sahits.game.graphic.data.image");

        try {
            Field f = imageLoader.getClass().getDeclaredField("unmarshaller");
            f.setAccessible(true);
            f.set(imageLoader, bean);
            Method m = imageLoader.getClass().getDeclaredMethod("loadImageFile");
            m.setAccessible(true);
            m.invoke(imageLoader);

        } catch (NoSuchFieldException|IllegalAccessException|NoSuchMethodException|InvocationTargetException e) {
            e.printStackTrace();
        }
        given(vessel.getOwner()).willReturn(player);
        given(vessel.getLocation()).willReturn(new Point2D(47, 11));
        given(vessel.pirateFlagProperty()).willReturn(new SimpleBooleanProperty(false));
        given(vessel.getShipType()).willReturn(EShipType.COG);
        given(player.getColor()).willReturn(EPlayerColor.BURGUNDY);

        // When
        ShipIcon shipIcon = new ShipIcon(vessel, player, imageLoader);

        // Then
        assertEquals(47 - 32, shipIcon.getLayoutX(), 0.001);
        assertEquals(11 -32, shipIcon.getLayoutY(), 0.001);
    }

}

Я думаюфактическая реализация метода теста в этом случае не имеет значения, так как он не выполняется, и я получаю следующие выходные данные:

javafx initialising...

javafx is initialised in 427ms



Test ignored.

org.junit.platform.commons.JUnitException: Chain of InvocationInterceptors never called invocation: org.junit.jupiter.engine.extension.TimeoutExtension, ch.sahits.game.openpatrician.testutilities.JavaFxInterceptor

    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.fail(InvocationInterceptorChain.java:137)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.verifyInvokedAtLeastOnce(InvocationInterceptorChain.java:130)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:44)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$8(ClassBasedTestDescriptor.java:371)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:369)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:193)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:77)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:132)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Поток пользовательского интерфейса JavaFX инициализируется, но фактический тест игнорируетсяи я не могу сделать голову или хвосты исключения. Отладка показывает, что interceptTestMethod никогда не вводится. Я предполагаю, что я поступаю неправильно, но как правильно?

...