Si je comprends bien, l'objectif principal de l'auteur de cette question est de découpler la couche JAX RS de la couche métier. Et de ne tester que la première. Nous devons résoudre deux problèmes de base ici :
- Exécutez en test un serveur web/application, mettez-y des composants JAX RS. dans ce serveur. Et seulement eux.
- Services d'entreprise fictifs dans les composants JAX RS et de la couche REST.
La première est résolue avec Arquillian. La seconde est parfaitement décrite dans arquillican et mock
Voici un exemple de code, il peut être différent si vous utilisez un autre serveur d'application, mais j'espère que vous comprendrez l'idée de base et les avantages.
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import com.brandmaker.skinning.service.SomeBean;
/**
* Created by alexandr on 31.07.15.
*/
@Path("/entities")
public class RestBean
{
@Inject
SomeBean bean;
@GET
public String getEntiry()
{
return bean.methodToBeMoked();
}
}
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.google.common.collect.Sets;
/**
*/
@ApplicationPath("res")
public class JAXRSConfiguration extends Application
{
@Override
public Set<Class<?>> getClasses()
{
return Sets.newHashSet(RestBean.class);
}
}
public class SomeBean
{
public String methodToBeMoked()
{
return "Original";
}
}
import javax.enterprise.inject.Specializes;
import com.brandmaker.skinning.service.SomeBean;
/**
*/
@Specializes
public class SomeBeanMock extends SomeBean
{
@Override
public String methodToBeMoked()
{
return "Mocked";
}
}
@RunWith(Arquillian.class)
public class RestBeanTest
{
@Deployment
public static WebArchive createDeployment() {
WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
.addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
System.out.println(war.toString(true));
return war;
}
@Test
public void should_create_greeting() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities");
//Building the request i.e a GET request to the RESTful Webservice defined
//by the URI in the WebTarget instance.
Invocation invocation = target.request().buildGet();
//Invoking the request to the RESTful API and capturing the Response.
Response response = invocation.invoke();
//As we know that this RESTful Webserivce returns the XML data which can be unmarshalled
//into the instance of Books by using JAXB.
Assert.assertEquals("Mocked", response.readEntity(String.class));
}
}
Quelques notes :
- La configuration de JAX RS sans web.xml est utilisée ici.
- Le client RS JAX est utilisé ici (pas de RESTEasy/Jersey, ils exposent une API plus pratique).
- Quand le test commence, le runner d'Arquillian commence à travailler. Ici vous pouvez trouver comment configurer les tests pour Arquillian avec le serveur d'application nécessaire.
- En fonction du serveur d'application choisi, une url dans le test sera un peu différent. Un autre port peut être utilisé. 8181 est utilisé par Glassfish Embedded dans mon exemple.
J'espère que ça aidera.
6 votes
Bonne question - cependant, je dirais que si vous effectuez des tests via HTTP, il me semble qu'il s'agit de tests d'intégration.
0 votes
Tom. Vous avez tout à fait raison. Nous devrions injecter un émulateur HTTP factice/un conteneur léger pour cela. Dans le monde node.js supertest fait cela. Vous pouvez émuler express.js.