Vertx 3 unit/integration testing

1,497 views
Skip to first unread message

bvil...@northplains.com

unread,
Apr 30, 2015, 5:39:16 AM4/30/15
to ve...@googlegroups.com
Hi,

quick question regarding tests in vertx 3. I have a test project where I create and deploy a Verticle in it own specific class, and this verticle starts a HTTP server.

I would like to perform a series of tests over this very same verticle (simple http requests and assertions to the responses).


Using the Vertx 3 TestSuite within a test class that extends from a Verticle, I am able to perform my tests correctly.


Next step is to move to a JUnit style (annotation based) test suite, which enables my gradle build to pickup the tests that need to be ran. I though the right way to do so would be to start the verticle I want to test in the method annotated with @Before, and therefore I wrote the following code:


@Before
public void setup() {
   
VertxOptions options = new VertxOptions();
   
System.setProperty("vertx.cwd", JAVA_DIR + TheVerticleToBeTested.class.getPackage().getName().replace(".", "/"));
   
Consumer<Vertx> runner = vertx -> {
       
try {
            vertx
.deployVerticle(TheVerticleToBeTested.class.getName());
       
} catch (Throwable t) {
            t
.printStackTrace();
       
}
   
};
   
if (options.isClustered()) {
       
Vertx.clusteredVertx(options, res -> {
           
if (res.succeeded()) {
               
Vertx vertx = res.result();
                runner
.accept(vertx);
           
} else {
                res
.cause().printStackTrace();
           
}
       
});
   
} else {
       
Vertx vertx = Vertx.vertx(options);
        runner
.accept(vertx);
   
}
}


It seems however that by the time my first method annotated as a @Test kicks in the HTTP server my verticle was supposed to create is non-existent: java.lang.AssertionError: Connection refused: localhost/127.0.0.1:8888

I'm quite new to Vertx 3, so I'm not too sure, but is there a proper way to make my test suite wait for the server to start?

Thanks

Julien Viet

unread,
Apr 30, 2015, 6:02:55 AM4/30/15
to ve...@googlegroups.com, bvil...@northplains.com
Hi,

have you tried Vertx. Unit ? it provides a JUnit extension and allow you to write async unit tests (even @Before/@After).


-- 
Julien Viet
www.julienviet.com
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

bvil...@northplains.com

unread,
Apr 30, 2015, 6:39:07 AM4/30/15
to ve...@googlegroups.com, bvil...@northplains.com
Hi Julien,

My code is based on those very same examples, however I'm not able to get around it for a couple of reasons.


The first being that the example starts a HTTP server in the setup (@Before) method, whereas I want to take advantage of the verticle I have preconfigured in my TheVerticleToBeTested class, however it seems that the start of the verticle is handed off to a different process, and therefore not in the same context as my test suite.

The same goes for using the regular TestSuite class within a test verticle, even if I create a custom task in gradle to run this test Verticle (using ant.java, for example), this creates a different process, so how will I be able to know when an Assertion Error is thrown and make gradle fail?


I should also mention that those examples are probably deprecated, because stuff like context.asyncAssertSuccess doesn't seem to exist in milestone4.

Julien Viet

unread,
Apr 30, 2015, 6:54:06 AM4/30/15
to ve...@googlegroups.com, bvil...@northplains.com, bvil...@northplains.com

On 30 Apr 2015 at 12:39:09, bvil...@northplains.com (bvil...@northplains.com) wrote:

Hi Julien,

My code is based on those very same examples, however I'm not able to get around it for a couple of reasons.


The first being that the example starts a HTTP server in the setup (@Before) method, whereas I want to take advantage of the verticle I have preconfigured in my TheVerticleToBeTested class, however it seems that the start of the verticle is handed off to a different process, and therefore not in the same context as my test suite.

it is not clear, what you mean by process / context . Can you clarify ?

my suggestion is that you replace the HTTP server by the TheVerticleToBeTested deployment, I don’t see why it wouldn’t work for this case.



The same goes for using the regular TestSuite class within a test verticle, even if I create a custom task in gradle to run this test Verticle (using ant.java, for example), this creates a different process, so how will I be able to know when an Assertion Error is thrown and make gradle fail?


I should also mention that those examples are probably deprecated, because stuff like context.asyncAssertSuccess doesn't seem to exist in milestone4.

indeed, it will be in the next milestone5 . It can be done without it but it requires more boiler plate code (the same MyJUnitTest.java does that in milestone4)

bvil...@northplains.com

unread,
Apr 30, 2015, 7:20:33 AM4/30/15
to ve...@googlegroups.com, bvil...@northplains.com
Hi Julien,

thanks for the reply, I suppose you mean something along these lines:


@RunWith(VertxUnitRunner.class)
public class TestCase {

   
private Vertx vertx;

   
@Before
    public void setup() {
       
vertx = Vertx.vertx();
       
JsonObject config = new JsonObject(ServerUtil.loadConfiguration("integration"));
       
DeploymentOptions options = new DeploymentOptions().setConfig(config);
       
vertx.deployVerticleObservable("com.test.vertx.FrontController", options)
               
.mergeWith(vertx.deployVerticleObservable("com.test.vertx.PermissionService"))
               
.mergeWith(vertx.deployVerticleObservable("com.test.vertx.EventHandler"))
               
.subscribe(next -> {},
                        error
-> System.err.println("Error deploying verticles"),
                       
() -> System.out.println("Finished deploying verticles!"));
   
}

   
@Test
    public void testSomething(TestContext context) {
       
Async async = context.async();
       
HttpClient client = vertx.createHttpClient();
       
HttpClientRequest req = client.get(8888, "localhost", "/site/rest/account/123");
        req
.exceptionHandler(err -> {
            context
.fail(err.getMessage());
       
});
        req
.handler(resp -> {
            context
.assertEquals(200, resp.statusCode());
            async
.complete();
       
});
        req
.end();
   
}
}


However the problem remains, test fails because there is no localhost:8888 to connect to.

By the way, integration json configuration is simply this: 

{
 
"port": 8888,
 
"host": "localhost"
}


The verticle works if I start it in a non-test related context.

bvil...@northplains.com

unread,
Apr 30, 2015, 7:42:48 AM4/30/15
to ve...@googlegroups.com, bvil...@northplains.com
Actually Julien, my mistake... your suggestion works perfectly!

Thank you
Reply all
Reply to author
Forward
0 new messages