You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am testing a Verticle which, while simple, can sometimes make a long-running network request at startup. As well, this network request counts against API limits, so I'd like to reduce the amount of times the startup procedure is called given that most of my tests don't care about this but require it to have run.
The correct behavior would be some sort of @BeforeAll annotation in JUnit5 but that runs only once for the ENTIRE run. There has been a lot of hand-wringing about this on junit5 github issues because, while you CAN achieve this effect, its not well documented. (c.f.: junit-team/junit5#1555 )
The difference is that if you attach a parameter to THAT store, it will not get closed until ALL of the tests are complete. This allows you to do something like this to, in effect, create a @BeforeEntireSuite.
By way of example I've created this little helper class that would be much better off inside vertx-junit5 as some convenience to get access to a Vertx that will not be torn down between sets of tests. You can extend this class and provide a keyname method and a method that starts the vertx/verticle pair as implementations of the abstract methods. Obviously there are a lot of kludges here, but i think it's a complete example.
packageai.brace.util;
importio.vertx.core.Vertx;
importorg.apache.logging.log4j.LogManager;
importorg.apache.logging.log4j.Logger;
importorg.junit.jupiter.api.extension.BeforeAllCallback;
importorg.junit.jupiter.api.extension.ExtensionContext;
importjava.util.concurrent.CompletableFuture;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.TimeoutException;
importstaticorg.assertj.core.api.Assertions.assertThat;
abstractclassGlobalVerticleExtensionimplementsBeforeAllCallback, ExtensionContext.Store.CloseableResource, AutoCloseable
{
privatestaticfinalExtensionContext.NamespaceNAMESPACE = ExtensionContext.Namespace.GLOBAL;
privatestaticfinalLoggerlogger = LogManager.getLogger();
/** * The verticle's vertx context. */privateVertxvertx = null;
/** * Return a unique name for this verticle so that we can potentially register multiple with junit * * @return A unique name for the verticle. */publicabstractStringgetName();
/** * Start the verticle and give back a vertx instance that will be shut down at the end. * * @param future complete or cancel this depending on how the startup procedure goes. */publicabstractvoidstart(finalCompletableFuture<Vertx> future);
privateGlobalVerticleExtensioncreate(finalStringname)
{
finalCompletableFuture<Vertx> future = newCompletableFuture<>();
logger.info("Starting " + name);
start(future);
try
{
vertx = future.get(10, TimeUnit.SECONDS);
}
catch (InterruptedExceptione)
{
thrownewRuntimeException(name + " startup interrupted.");
}
catch (ExecutionExceptione)
{
thrownewRuntimeException(e);
}
catch (TimeoutExceptione)
{
thrownewRuntimeException(name + " startup timeout.");
}
assertThat(vertx).isNotNull();
assertThat(vertx.deploymentIDs()).isNotEmpty().hasSize(1);
logger.info(name + " startup complete.");
returnthis;
}
@OverridepublicvoidbeforeAll(ExtensionContextcontext)
{
// N.B.: If you don't include getRoot() here this will become a beforeAll / close handler for every annotated// test class. This might actually be very useful, but for this class we want code to exec once per test run.context.getRoot().getStore(NAMESPACE).getOrComputeIfAbsent(getName() + "_global_verticle", this::create);
}
@Overridepublicvoidclose()
{
if (vertx == null)
{
return;
}
finalCompletableFuture<Boolean> future = newCompletableFuture<>();
vertx.close(result -> future.complete(result.succeeded()));
try
{
future.get(10, TimeUnit.SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutExceptione)
{
// This is an exit routine, so log then eat the exception.logger.error(e);
}
vertx = null;
}
}
I am testing a Verticle which, while simple, can sometimes make a long-running network request at startup. As well, this network request counts against API limits, so I'd like to reduce the amount of times the startup procedure is called given that most of my tests don't care about this but require it to have run.
The correct behavior would be some sort of @BeforeAll annotation in JUnit5 but that runs only once for the ENTIRE run. There has been a lot of hand-wringing about this on junit5 github issues because, while you CAN achieve this effect, its not well documented. (c.f.: junit-team/junit5#1555 )
For vertx-junit, what we need is the ability to add a parameter to the root extension context, instead of the one passed directly by junit5. Specifically, this line https://github.com/vert-x3/vertx-junit5/blob/master/vertx-junit5/src/main/java/io/vertx/junit5/VertxExtension.java#L162, but
The difference is that if you attach a parameter to THAT store, it will not get closed until ALL of the tests are complete. This allows you to do something like this to, in effect, create a
@BeforeEntireSuite
.By way of example I've created this little helper class that would be much better off inside vertx-junit5 as some convenience to get access to a Vertx that will not be torn down between sets of tests. You can extend this class and provide a keyname method and a method that starts the vertx/verticle pair as implementations of the abstract methods. Obviously there are a lot of kludges here, but i think it's a complete example.
Note: the example at https://github.com/vert-x3/vertx-junit5/blob/master/vertx-junit5/src/test/java/io/vertx/junit5/OtherExtension.java#L38 does not quite apply because the function it's calling in
VertxExtension.java
doesn't give access tocontext.getRoot()
.The text was updated successfully, but these errors were encountered: