Вот простой upocationInterceptor , который предназначен для запуска тестов в EDT.
Код: Выделить всё
import org.fest.swing.annotation.RunsInEDT;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
import org.junit.platform.commons.function.Try;
import javax.swing.SwingUtilities;
import java.lang.annotation.Retention;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class EdtExtension implements InvocationInterceptor {
@Override
public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable {
if (shouldRunInEdt(invocationContext)) invokeInEdt(invocation);
else invocation.proceed();
}
/**
* @apiNote FEST's {@link RunsInEDT} has a default {@link Retention} and hence is not reflectively accessible. We need to check our own runtime annotation instead.
*/
private static boolean shouldRunInEdt(ReflectiveInvocationContext invocationContext) {
Class testClass = invocationContext.getTargetClass();
Method testMethod = invocationContext.getExecutable();
return hasEdtAnnotation(testClass) || hasEdtAnnotation(testMethod);
}
private static boolean hasEdtAnnotation(AnnotatedElement annotatedElement) {
return annotatedElement.getAnnotation(EdtRun.class) != null;
}
private void invokeInEdt(Invocation invocation) {
Try.call(() -> invokeAndWait(invocation));
}
private Void invokeAndWait(Invocation invocation) throws InterruptedException, InvocationTargetException {
SwingUtilities.invokeAndWait(() -> {
try {
invocation.proceed();
} catch (Throwable e) {
throw new AssertionError(e);
}
});
return null;
}
}
< /code>
import org.fest.swing.annotation.RunsInEDT;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EdtRun {
}
< /code>
Все тесты проходят. < /p>
Но на самом деле это плохо! Я целенаправленно включил тест с неисправным утверждением, ожидая, что он потерпит неудачу. Вопреки моим ожиданиям, AssertionError Код: Выделить всё
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import java.awt.EventQueue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class EdtExtensionTest {
@Nested
@ExtendWith(EdtExtension.class)
class AnnotatedPerMethod {
@Test
void ifNotAnnotated_doesNotRunInEdt() {
assertFalse(EventQueue.isDispatchThread());
}
@Test
@EdtRun
void ifAnnotated_runsInEdt() {
assertTrue(EventQueue.isDispatchThread());
}
}
@Nested
@EdtRun
@ExtendWith(EdtExtension.class)
class AnnotatedPerClass {
@Test
void ifNotAnnotated_runsInEdt() {
// ???
boolean isEdt = EventQueue.isDispatchThread(); // true
assertFalse(isEdt); // but AssertionError is swallowed by EDT
}
@Test
@EdtRun
void ifAnnotated_runsInEdt() {
assertTrue(EventQueue.isDispatchThread());
}
}
@Nested
class AnnotatedPerMethodButNotExtended {
@Test
@EdtRun
void ifNotAnnotated_doesNotRunInEdt() {
assertFalse(EventQueue.isDispatchThread());
}
@Test
@EdtRun
void ifAnnotated_doesNotRunInEdt() {
assertFalse(EventQueue.isDispatchThread());
}
}
@Nested
@EdtRun
class AnnotatedPerClassButNotExtended {
@Test
void ifNotAnnotated_doesNotRunInEdt() {
assertFalse(EventQueue.isDispatchThread());
}
@Test
@EdtRun
void ifAnnotated_doesNotRunInEdt() {
assertFalse(EventQueue.isDispatchThread());
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... s-from-edt