Introduction
Currently, Jetty 9 and Tomcat 8 are supported out of the box (through the specific artifacts). But, what if you want to provide a custom implementation for a specific embedded server?
Starting with version 0.8.0, junit-servers
use the service provider interface available since Java 6: it means that it is now possible
to provide any custom implementation!
Example
1- The custom implementation
Suppose this implementation of EmbeddedServer
:
package com.myapp;
import com.github.mjeanroy.junit.servers.servers.EmbeddedServer;
import javax.servlet.ServletContext;
public class MyCustomEmbeddedServer implements EmbeddedServer<MyCustomConfiguration> {
private final MyCustomConfiguration configuration;
private boolean started;
public MyCustomEmbeddedServer() {
this.configuration = new MyCustomConfiguration();
this.started = false;
}
public MyCustomEmbeddedServer(MyCustomConfiguration configuration) {
this.configuration = configuration;
this.started = false;
}
@Override
public void start() {
this.started = true;
System.out.println("Starting Embedded Server");
}
@Override
public void stop() {
this.started = false;
System.out.println("Stopping Embedded Server");
}
@Override
public void restart() {
stop();
start();
}
@Override
public MyCustomConfiguration getConfiguration() {
return configuration;
}
@Override
public boolean isStarted() {
return started;
}
@Override
public String getScheme() {
return "http";
}
@Override
public String getHost() {
return "localhost";
}
@Override
public int getPort() {
return 80;
}
@Override
public String getPath() {
return "/";
}
@Override
public String getUrl() {
return getScheme() + "://" + getHost() + ":" + getPort() + getPath();
}
@Override
public ServletContext getServletContext() {
throw new UnsupportedOperationException("ServletContext is not supported by this implementation");
}
}
Here is the configuration class:
package com.myapp;
import com.github.mjeanroy.junit.servers.servers.AbstractConfiguration;
public class MyCustomConfiguration extends AbstractConfiguration {
public MyCustomConfiguration() {
super();
}
}
Note that this is not a “real” implementation, since it does not really starts/stop a real embedded server… but you got the main idea ;)
2- The test
Here is our unit test:
package com.myapp;
import com.github.mjeanroy.junit.servers.annotations.TestServer;
import com.github.mjeanroy.junit.servers.junit4.JunitServerRunner;
import com.github.mjeanroy.junit.servers.servers.EmbeddedServer;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(JunitServerRunner.class)
public class MyTest {
@TestServer
public static EmbeddedServer server;
@Test
public void should_be_started() {
Assert.assertTrue(server.isStarted());
}
}
3- Register the custom implementation
So, how can we use our custom MyCustomEmbeddedServer
in our unit test?
First of all, you need to implement an instance of EmbeddedServerProvider
:
package com.myapp;
import com.github.mjeanroy.junit.servers.servers.EmbeddedServer;
import com.github.mjeanroy.junit.servers.servers.EmbeddedServerProvider;
public class MyCustomEmbeddedServerProvider implements EmbeddedServerProvider<MyCustomConfiguration> {
@Override
public EmbeddedServer<MyCustomConfiguration> instantiate() {
return new MyCustomEmbeddedServer();
}
@Override
public EmbeddedServer<MyCustomConfiguration> instantiate(MyCustomConfiguration configuration) {
return new MyCustomEmbeddedServer(configuration);
}
}
Once done, create a file named com.github.mjeanroy.junit.servers.servers.EmbeddedServerProvider
in META-INF/services
to register our custom implementation.
This file should contains a single line: the fully qualified name of your provider implementation.
com.myapp.MyCustomEmbeddedServerProvider
You’re done! Now, the JunitServerRunner
annotation will automatically detect your custom implementation and will use it in your unit test ;)
Note that junit-servers-jetty
and junit-servers-tomcat
now use the exact same api: