├── README
├── mjl-jersey-build
└── pom.xml
├── mjl-jersey-client
├── pom.xml
└── src
│ └── main
│ └── java
│ └── de
│ └── codecentric
│ └── mjl
│ └── jerseytest
│ └── client
│ └── TodoClient.java
├── mjl-jersey-common
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── de
│ │ └── codecentric
│ │ └── mjl
│ │ └── jerseytest
│ │ └── exceptions
│ │ └── TodoNotFoundException.java
│ └── webapp
│ └── WEB-INF
│ └── web.xml
└── mjl-jersey-server
├── pom.xml
└── src
├── main
├── java
│ └── de
│ │ └── codecentric
│ │ └── mjl
│ │ └── jerseytest
│ │ ├── providers
│ │ ├── NotFoundMapper.java
│ │ └── TodoServiceProvider.java
│ │ ├── resources
│ │ └── TodoResource.java
│ │ └── services
│ │ └── TodoService.java
└── webapp
│ └── WEB-INF
│ └── web.xml
└── test
└── java
└── de
└── codecentric
└── mjl
└── jerseytest
├── FastTodoResourceTest.java
├── TodoResourceTest.java
├── TodoResourceWithLowLevelContainer.java
└── helpers
├── FastJerseyTest.java
└── FilteringInMemoryTestContainerFactory.java
/README:
--------------------------------------------------------------------------------
1 | Writing lightweight REST integration tests with the Jersey Test Framework
2 |
3 | To compile the project, simply run "mvn package" inside the mjl-jersey-build directory. To view the project in eclipse, best use the maven eclipse plugin ("mvn eclipse:eclipse") and import as existing project.
4 |
5 | There is a blog post corresponding to this mini-tutorial: http://mjlex.blogspot.de/2012/04/writing-lightweight-rest-integration.html.
--------------------------------------------------------------------------------
/mjl-jersey-build/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | de.codecentric.mjl
7 | mjl-jersey-build
8 | mjl-jersey-build
9 | pom
10 | 1.0.0-SNAPSHOT
11 |
12 |
13 | 1.6
14 | 1.12
15 | 1.5.10
16 |
17 |
18 |
19 | ../mjl-jersey-client/
20 | ../mjl-jersey-server/
21 | ../mjl-jersey-common/
22 |
23 |
24 |
25 |
26 |
27 | org.apache.commons
28 | commons-lang3
29 | 3.0
30 |
31 |
32 |
33 | com.sun.jersey
34 | jersey-server
35 | ${jersey-version}
36 |
37 |
38 | com.sun.jersey.contribs
39 | jersey-multipart
40 | ${jersey-version}
41 |
42 |
43 | com.sun.jersey
44 | jersey-json
45 | ${jersey-version}
46 |
47 |
48 | com.sun.jersey
49 | jersey-client
50 | ${jersey-version}
51 |
52 |
53 | com.sun.jersey
54 | jersey-core
55 | ${jersey-version}
56 |
57 |
58 | com.sun.jersey
59 | jersey-servlet
60 | ${jersey-version}
61 |
62 |
63 | com.sun.jersey.jersey-test-framework
64 | jersey-test-framework-inmemory
65 | ${jersey-version}
66 | test
67 |
68 |
69 | com.sun.jersey.jersey-test-framework
70 | jersey-test-framework-grizzly2
71 | ${jersey-version}
72 | test
73 |
74 |
75 |
76 |
77 | org.mockito
78 | mockito-core
79 | 1.9.0
80 | test
81 |
82 |
83 | junit
84 | junit
85 | 4.8.2
86 | test
87 |
88 |
89 | org.hamcrest
90 | hamcrest-core
91 | 1.1
92 | test
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | org.apache.maven.plugins
101 | maven-compiler-plugin
102 |
103 | ${java-version}
104 | ${java-version}
105 |
106 |
107 |
108 | org.apache.maven.plugins
109 | maven-eclipse-plugin
110 | 2.8
111 |
112 | 2.0
113 |
114 |
115 |
116 | org.apache.maven.plugins
117 | maven-dependency-plugin
118 |
119 |
120 | install
121 | install
122 |
123 | sources
124 |
125 |
126 |
127 |
128 |
129 | org.apache.maven.plugins
130 | maven-site-plugin
131 | 3.0
132 |
133 | ../site
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/mjl-jersey-client/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | de.codecentric.mjl
5 | mjl-jersey-client
6 | 1.0.0-SNAPSHOT
7 | mjl-jersey-client
8 |
9 | de.codecentric.mjl
10 | mjl-jersey-build
11 | 1.0.0-SNAPSHOT
12 | ../mjl-jersey-build
13 |
14 |
15 |
16 | de.codecentric.mjl
17 | mjl-jersey-common
18 | 1.0.0-SNAPSHOT
19 |
20 |
21 | org.apache.commons
22 | commons-lang3
23 |
24 |
25 | com.sun.jersey
26 | jersey-server
27 |
28 |
29 | com.sun.jersey.contribs
30 | jersey-multipart
31 |
32 |
33 | com.sun.jersey
34 | jersey-json
35 |
36 |
37 | com.sun.jersey
38 | jersey-client
39 |
40 |
41 | com.sun.jersey
42 | jersey-core
43 |
44 |
45 | com.sun.jersey
46 | jersey-servlet
47 |
48 |
49 | com.sun.jersey.jersey-test-framework
50 | jersey-test-framework-inmemory
51 | test
52 |
53 |
54 | com.sun.jersey.jersey-test-framework
55 | jersey-test-framework-grizzly2
56 | test
57 |
58 |
59 | junit
60 | junit
61 | test
62 |
63 |
64 | org.mockito
65 | mockito-core
66 | test
67 |
68 |
69 | org.hamcrest
70 | hamcrest-core
71 | test
72 |
73 |
74 |
--------------------------------------------------------------------------------
/mjl-jersey-client/src/main/java/de/codecentric/mjl/jerseytest/client/TodoClient.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.client;
2 |
3 | import com.sun.jersey.api.client.Client;
4 | import com.sun.jersey.api.client.ClientResponse.Status;
5 | import com.sun.jersey.api.client.UniformInterfaceException;
6 | import com.sun.jersey.api.client.WebResource;
7 |
8 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
9 |
10 | public class TodoClient {
11 |
12 | public static final String TODO_RESOURCE_PATH = "/todo";
13 |
14 | private final String uri;
15 |
16 | private final Client client = new Client();
17 |
18 | public TodoClient(String uri) {
19 | this.uri = uri;
20 | }
21 |
22 | public WebResource resource() {
23 | return client.resource(uri).path(TODO_RESOURCE_PATH);
24 | }
25 |
26 | public WebResource resource(String todo) {
27 | return resource().path("/" + todo);
28 | }
29 |
30 | public String getAllTodos() {
31 | String todos = resource().get(String.class);
32 | return todos;
33 | }
34 |
35 | public void addTodo(String todoToAdd) {
36 | resource().post(todoToAdd);
37 | }
38 |
39 | public void removeTodo(String todoToRemove) {
40 | try {
41 | resource(todoToRemove).delete();
42 | } catch (UniformInterfaceException e) {
43 | if (e.getResponse().getClientResponseStatus() == Status.BAD_REQUEST
44 | && "TodoNotFoundException".equals(e.getResponse().getEntity(String.class))) {
45 | throw new TodoNotFoundException("Todo '" + todoToRemove + "' not found");
46 | } else {
47 | throw e;
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/mjl-jersey-common/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | de.codecentric.mjl
5 | mjl-jersey-common
6 | 1.0.0-SNAPSHOT
7 | mjl-jersey-common
8 |
9 | de.codecentric.mjl
10 | mjl-jersey-build
11 | 1.0.0-SNAPSHOT
12 | ../mjl-jersey-build
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/mjl-jersey-common/src/main/java/de/codecentric/mjl/jerseytest/exceptions/TodoNotFoundException.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.exceptions;
2 |
3 | public class TodoNotFoundException extends RuntimeException {
4 | public TodoNotFoundException() {
5 | super();
6 | }
7 |
8 | public TodoNotFoundException(String msg) {
9 | super(msg);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/mjl-jersey-common/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Jersey Web Application
7 | com.sun.jersey.spi.container.servlet.ServletContainer
8 |
9 | com.sun.jersey.config.property.packages
10 | de.codecentric.mjl
11 |
12 | 1
13 |
14 |
15 | Jersey Web Application
16 | /webresources/*
17 |
18 |
19 |
--------------------------------------------------------------------------------
/mjl-jersey-server/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | de.codecentric.mjl
5 | mjl-jersey-server
6 | war
7 | 1.0.0-SNAPSHOT
8 | mjl-jersey-server
9 |
10 | de.codecentric.mjl
11 | mjl-jersey-build
12 | 1.0.0-SNAPSHOT
13 | ../mjl-jersey-build
14 |
15 |
16 |
17 | de.codecentric.mjl
18 | mjl-jersey-common
19 | 1.0.0-SNAPSHOT
20 |
21 |
22 | org.apache.commons
23 | commons-lang3
24 |
25 |
26 | com.sun.jersey
27 | jersey-server
28 |
29 |
30 | com.sun.jersey.contribs
31 | jersey-multipart
32 |
33 |
34 | com.sun.jersey
35 | jersey-json
36 |
37 |
38 | com.sun.jersey
39 | jersey-client
40 |
41 |
42 | com.sun.jersey
43 | jersey-core
44 |
45 |
46 | com.sun.jersey
47 | jersey-servlet
48 |
49 |
50 | com.sun.jersey.jersey-test-framework
51 | jersey-test-framework-inmemory
52 | test
53 |
54 |
55 | com.sun.jersey.jersey-test-framework
56 | jersey-test-framework-grizzly2
57 | test
58 |
59 |
60 | junit
61 | junit
62 | test
63 |
64 |
65 | org.mockito
66 | mockito-core
67 | 1.8.5
68 | test
69 |
70 |
71 | de.codecentric.mjl
72 | mjl-jersey-client
73 | 1.0.0-SNAPSHOT
74 | test
75 |
76 |
77 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/main/java/de/codecentric/mjl/jerseytest/providers/NotFoundMapper.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.providers;
2 |
3 | import javax.ws.rs.core.Response;
4 | import javax.ws.rs.ext.ExceptionMapper;
5 | import javax.ws.rs.ext.Provider;
6 |
7 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
8 |
9 | @Provider
10 | public class NotFoundMapper implements ExceptionMapper {
11 | @Override
12 | public Response toResponse(TodoNotFoundException e) {
13 | return Response.status(Response.Status.BAD_REQUEST).entity("TodoNotFoundException").build();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/main/java/de/codecentric/mjl/jerseytest/providers/TodoServiceProvider.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.providers;
2 |
3 | import javax.ws.rs.core.Context;
4 | import javax.ws.rs.ext.Provider;
5 |
6 | import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
7 |
8 | import de.codecentric.mjl.jerseytest.services.TodoService;
9 |
10 | @Provider
11 | public class TodoServiceProvider extends SingletonTypeInjectableProvider {
12 |
13 | public TodoServiceProvider() {
14 | super(TodoService.class, new TodoService());
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/main/java/de/codecentric/mjl/jerseytest/resources/TodoResource.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.resources;
2 |
3 | import javax.ws.rs.Consumes;
4 | import javax.ws.rs.DELETE;
5 | import javax.ws.rs.GET;
6 | import javax.ws.rs.POST;
7 | import javax.ws.rs.Path;
8 | import javax.ws.rs.PathParam;
9 | import javax.ws.rs.Produces;
10 | import javax.ws.rs.core.Context;
11 |
12 | import org.apache.commons.lang3.StringUtils;
13 |
14 | import de.codecentric.mjl.jerseytest.services.TodoService;
15 |
16 | /**
17 | * Example resource class hosted at the URI path "/myresource"
18 | */
19 | @Path("/todo")
20 | public class TodoResource {
21 |
22 | @Context
23 | private TodoService todoService;
24 |
25 | @GET
26 | @Produces("text/plain")
27 | public String getTodos() {
28 | return StringUtils.join(todoService.getAllTodos(), ",");
29 | }
30 |
31 | @POST
32 | @Consumes("text/plain")
33 | public void addTodo(String newTodo) {
34 | todoService.addTodo(newTodo);
35 | }
36 |
37 | @DELETE
38 | @Path("/{todo}")
39 | public void removeTodo(@PathParam("todo") String todoToRemove) {
40 | todoService.removeTodo(todoToRemove);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/main/java/de/codecentric/mjl/jerseytest/services/TodoService.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.services;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
7 |
8 | public class TodoService {
9 |
10 | List todos = new ArrayList();
11 |
12 | public List getAllTodos() {
13 | return new ArrayList(todos);
14 | }
15 |
16 | public void addTodo(String todo) {
17 | todos.add(todo);
18 | }
19 |
20 | public void removeTodo(String todo) {
21 | if (todos.remove(todo) == false) {
22 | throw new TodoNotFoundException("Todo '" + todo + "' not found.");
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Jersey Web Application
7 | com.sun.jersey.spi.container.servlet.ServletContainer
8 |
9 | com.sun.jersey.config.property.packages
10 | de.codecentric.mjl
11 |
12 | 1
13 |
14 |
15 | Jersey Web Application
16 | /*
17 |
18 |
19 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/test/java/de/codecentric/mjl/jerseytest/FastTodoResourceTest.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest;
2 |
3 | import javax.ws.rs.core.Context;
4 | import javax.ws.rs.ext.Provider;
5 |
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.BeforeClass;
9 | import org.junit.Test;
10 | import org.mockito.Mockito;
11 | import org.mockito.internal.util.reflection.Whitebox;
12 |
13 | import com.sun.jersey.api.client.ClientResponse;
14 | import com.sun.jersey.api.client.ClientResponse.Status;
15 | import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
16 |
17 | import de.codecentric.mjl.jerseytest.client.TodoClient;
18 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
19 | import de.codecentric.mjl.jerseytest.helpers.FastJerseyTest;
20 | import de.codecentric.mjl.jerseytest.helpers.FilteringInMemoryTestContainerFactory;
21 | import de.codecentric.mjl.jerseytest.providers.NotFoundMapper;
22 | import de.codecentric.mjl.jerseytest.resources.TodoResource;
23 | import de.codecentric.mjl.jerseytest.services.TodoService;
24 |
25 | public class FastTodoResourceTest extends FastJerseyTest {
26 |
27 | public static TodoService todoServiceMock = Mockito.mock(TodoService.class);
28 |
29 | @BeforeClass
30 | public static void configure() {
31 | addClass(TodoResource.class);
32 | addClass(NotFoundMapper.class);
33 | addProviderForContext(TodoService.class, todoServiceMock);
34 | setTestContainerFactory(new FilteringInMemoryTestContainerFactory());
35 | }
36 |
37 | @Before
38 | public void resetMocks() {
39 | // the mock is stored in a static field and must be reset manually before each test
40 | Mockito.reset(todoServiceMock);
41 | }
42 |
43 | @Test(expected = TodoNotFoundException.class)
44 | public void removeTodoShouldThrowNotFoundException() {
45 | final String todo = "test-todo";
46 | Mockito.doThrow(new TodoNotFoundException()).when(todoServiceMock).removeTodo(todo);
47 | todoClient().removeTodo(todo);
48 | }
49 |
50 | @Test
51 | public void shouldReturn400OnNotFoundException() {
52 | String todo = "test-todo";
53 | Mockito.doThrow(new TodoNotFoundException()).when(todoServiceMock).removeTodo(todo);
54 | ClientResponse response = resource().path("todo/" + todo).delete(ClientResponse.class);
55 | Assert.assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
56 | Assert.assertEquals("TodoNotFoundException", response.getEntity(String.class));
57 | }
58 |
59 | private TodoClient todoClient() {
60 | TodoClient todoClient = new TodoClient(getBaseUri().toString());
61 | Whitebox.setInternalState(todoClient, "client", client());
62 | return todoClient;
63 | }
64 |
65 | @Provider
66 | public static class MockTodoServiceProvider extends
67 | SingletonTypeInjectableProvider {
68 |
69 | public MockTodoServiceProvider() {
70 | super(TodoService.class, todoServiceMock);
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/mjl-jersey-server/src/test/java/de/codecentric/mjl/jerseytest/TodoResourceTest.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest;
2 |
3 | import javax.ws.rs.core.Context;
4 | import javax.ws.rs.ext.Provider;
5 |
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.mockito.Mockito;
10 | import org.mockito.internal.util.reflection.Whitebox;
11 |
12 | import com.sun.jersey.api.client.ClientResponse;
13 | import com.sun.jersey.api.client.ClientResponse.Status;
14 | import com.sun.jersey.api.core.ClassNamesResourceConfig;
15 | import com.sun.jersey.spi.container.servlet.WebComponent;
16 | import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
17 | import com.sun.jersey.test.framework.JerseyTest;
18 | import com.sun.jersey.test.framework.WebAppDescriptor;
19 | import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
20 | import com.sun.jersey.test.framework.spi.container.grizzly2.web.GrizzlyWebTestContainerFactory;
21 |
22 | import de.codecentric.mjl.jerseytest.client.TodoClient;
23 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
24 | import de.codecentric.mjl.jerseytest.providers.NotFoundMapper;
25 | import de.codecentric.mjl.jerseytest.resources.TodoResource;
26 | import de.codecentric.mjl.jerseytest.services.TodoService;
27 |
28 | public class TodoResourceTest extends JerseyTest {
29 |
30 | public static TodoService todoServiceMock = Mockito.mock(TodoService.class);
31 |
32 | @Override
33 | public WebAppDescriptor configure() {
34 | return new WebAppDescriptor.Builder()
35 | .initParam(WebComponent.RESOURCE_CONFIG_CLASS,
36 | ClassNamesResourceConfig.class.getName())
37 | .initParam(
38 | ClassNamesResourceConfig.PROPERTY_CLASSNAMES,
39 | TodoResource.class.getName() + ";"
40 | + MockTodoServiceProvider.class.getName() + ";"
41 | + NotFoundMapper.class.getName()).build();
42 | }
43 |
44 | @Override
45 | public TestContainerFactory getTestContainerFactory() {
46 | return new GrizzlyWebTestContainerFactory();
47 | }
48 |
49 | @Before
50 | public void resetMocks() {
51 | // the mock is stored in a static field and must be reset manually before each test
52 | Mockito.reset(todoServiceMock);
53 | }
54 |
55 | @Test(expected = TodoNotFoundException.class)
56 | public void removeTodoShouldThrowNotFoundException() {
57 | final String todo = "test-todo";
58 | Mockito.doThrow(new TodoNotFoundException()).when(todoServiceMock).removeTodo(todo);
59 | todoClient().removeTodo(todo);
60 | }
61 |
62 | @Test
63 | public void shouldReturn400OnNotFoundException() {
64 | String todo = "test-todo";
65 | Mockito.doThrow(new TodoNotFoundException()).when(todoServiceMock).removeTodo(todo);
66 | ClientResponse response = resource().path("todo/" + todo).delete(ClientResponse.class);
67 | Assert.assertEquals(Status.BAD_REQUEST, response.getClientResponseStatus());
68 | Assert.assertEquals("TodoNotFoundException", response.getEntity(String.class));
69 | }
70 |
71 | private TodoClient todoClient() {
72 | TodoClient todoClient = new TodoClient(getBaseURI().toString());
73 | Whitebox.setInternalState(todoClient, "client", client());
74 | return todoClient;
75 | }
76 |
77 | @Provider
78 | public static class MockTodoServiceProvider extends
79 | SingletonTypeInjectableProvider {
80 |
81 | public MockTodoServiceProvider() {
82 | super(TodoService.class, todoServiceMock);
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/mjl-jersey-server/src/test/java/de/codecentric/mjl/jerseytest/TodoResourceWithLowLevelContainer.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest;
2 |
3 | import javax.ws.rs.core.Context;
4 |
5 | import org.junit.Before;
6 | import org.junit.Test;
7 | import org.mockito.Mockito;
8 | import org.mockito.internal.util.reflection.Whitebox;
9 |
10 | import com.sun.jersey.api.core.DefaultResourceConfig;
11 | import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
12 | import com.sun.jersey.test.framework.JerseyTest;
13 | import com.sun.jersey.test.framework.LowLevelAppDescriptor;
14 | import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
15 | import com.sun.jersey.test.framework.spi.container.grizzly2.GrizzlyTestContainerFactory;
16 |
17 | import de.codecentric.mjl.jerseytest.client.TodoClient;
18 | import de.codecentric.mjl.jerseytest.exceptions.TodoNotFoundException;
19 | import de.codecentric.mjl.jerseytest.providers.NotFoundMapper;
20 | import de.codecentric.mjl.jerseytest.resources.TodoResource;
21 | import de.codecentric.mjl.jerseytest.services.TodoService;
22 |
23 | public class TodoResourceWithLowLevelContainer extends JerseyTest {
24 |
25 | public static TodoService todoServiceMock = Mockito.mock(TodoService.class);
26 |
27 | @Override
28 | public LowLevelAppDescriptor configure() {
29 | DefaultResourceConfig resourceConfig = new DefaultResourceConfig();
30 | resourceConfig.getSingletons().add(
31 | new SingletonTypeInjectableProvider(TodoService.class,
32 | todoServiceMock) {
33 | });
34 | resourceConfig.getClasses().add(NotFoundMapper.class);
35 | resourceConfig.getClasses().add(TodoResource.class);
36 | return new LowLevelAppDescriptor.Builder(resourceConfig).build();
37 | }
38 |
39 | @Override
40 | public TestContainerFactory getTestContainerFactory() {
41 | return new GrizzlyTestContainerFactory();
42 | }
43 |
44 | @Before
45 | public void resetMocks() {
46 | // the mock is stored in a static field and must be reset manually before each test
47 | Mockito.reset(todoServiceMock);
48 | }
49 |
50 | @Test(expected = TodoNotFoundException.class)
51 | public void removeTodoShouldThrowNotFoundException() {
52 | final String todo = "test-todo";
53 | Mockito.doThrow(new TodoNotFoundException()).when(todoServiceMock).removeTodo(todo);
54 | todoClient().removeTodo(todo);
55 | }
56 |
57 | private TodoClient todoClient() {
58 | TodoClient todoClient = new TodoClient(getBaseURI().toString());
59 | Whitebox.setInternalState(todoClient, "client", client());
60 | return todoClient;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/test/java/de/codecentric/mjl/jerseytest/helpers/FastJerseyTest.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.helpers;
2 |
3 | import java.net.URI;
4 |
5 | import javax.ws.rs.core.Context;
6 | import javax.ws.rs.core.UriBuilder;
7 |
8 | import org.junit.AfterClass;
9 | import org.junit.Before;
10 | import org.junit.BeforeClass;
11 |
12 | import com.sun.jersey.api.client.Client;
13 | import com.sun.jersey.api.client.WebResource;
14 | import com.sun.jersey.api.core.DefaultResourceConfig;
15 | import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
16 | import com.sun.jersey.test.framework.AppDescriptor;
17 | import com.sun.jersey.test.framework.LowLevelAppDescriptor;
18 | import com.sun.jersey.test.framework.spi.container.TestContainer;
19 | import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
20 |
21 | /**
22 | * An abstract JUnit 4.x-based unit test class for testing JAX-RS and Jersey-based applications
23 | * inspired by the JerseyTest class of the jersey test framework.
24 | *
25 | * LowLevelJerseyTest differs from JerseyTest in that only low-level test-containsers can be used.
26 | * Taking advantage of this restriction, LowLevelJerseyTest allows easy mocking of objects injected
27 | * via @Context and on-the-fly configuration of request- and response-filters. Another difference to
28 | * JerseyTest is, that the test-container is only started once per test-suite (and not once per
29 | * test). Although this contradicts with the rule of absolute isolation of test-cases, the
30 | * performance gain outweighs this shortcoming.
31 | *
32 | * The test-container has to be configured in methods annotated with @BeforeClass using the static
33 | * methods {@link #addClass}, {@link #addSingleton}, {@link #addFilter},
34 | * {@link #addProviderForContext}, and so on. Note, that the test-container is initialized and start
35 | * before any @Before annotated methods are executed. So calling any of the above methods in @Before
36 | * annotated methods won't have any effect.
37 | *
38 | * The method {@link #resource()} returns a {@link WebResource}, that is already configured to point
39 | * to the root path of the test-container.
40 | *
41 | * @author Michael Lex
42 | */
43 | abstract public class FastJerseyTest {
44 |
45 | private static DefaultResourceConfig resourceConfig = new DefaultResourceConfig();
46 |
47 | private static TestContainerFactory testContainerFactory;
48 |
49 | private static TestContainer testContainer;
50 |
51 | private static Client client;
52 |
53 | public static void addClass(Class> resourceClass) {
54 | resourceConfig.getClasses().add(resourceClass);
55 | }
56 |
57 | public static void addSingleton(Object resourceSingleton) {
58 | resourceConfig.getSingletons().add(resourceSingleton);
59 | }
60 |
61 | public static void addProviderForContext(Class contextClass, T contextObject) {
62 | addSingleton(new SingletonTypeInjectableProvider(contextClass, contextObject) {
63 | });
64 | }
65 |
66 | public static void addRequestFilter(Object filter) {
67 | resourceConfig.getContainerRequestFilters().add(filter);
68 | }
69 |
70 | public static void addResponseFilter(Object filter) {
71 | resourceConfig.getContainerResponseFilters().add(filter);
72 | }
73 |
74 | public static void setTestContainerFactory(TestContainerFactory newTestContainerFactory) {
75 | testContainerFactory = newTestContainerFactory;
76 | }
77 |
78 | @BeforeClass
79 | public static void cleanStaticVariables() {
80 | resourceConfig = new DefaultResourceConfig();
81 | }
82 |
83 | public static void initServer() {
84 | AppDescriptor ad = new LowLevelAppDescriptor.Builder(resourceConfig).build();
85 | TestContainerFactory tcf = testContainerFactory;
86 | if (tcf == null) {
87 | tcf = new FilteringInMemoryTestContainerFactory();
88 | }
89 | testContainer = tcf.create(UriBuilder.fromUri("http://localhost/").port(9998).build(), ad);
90 | client = testContainer.getClient();
91 | if (client == null) {
92 | client = Client.create(ad.getClientConfig());
93 | }
94 | }
95 |
96 | public static void startServer() {
97 | if (testContainer != null) {
98 | testContainer.start();
99 | }
100 | }
101 |
102 | @AfterClass
103 | public static void stopServer() {
104 | testContainer.stop();
105 | testContainer = null;
106 | client = null;
107 | }
108 |
109 | public Client client() {
110 | return client;
111 | }
112 |
113 | public URI getBaseUri() {
114 | return testContainer.getBaseUri();
115 | }
116 |
117 | public WebResource resource() {
118 | return client.resource(getBaseUri());
119 | }
120 |
121 | @Before
122 | public void startServerBeforeFirstTestRun() {
123 | if (testContainer == null) {
124 | initServer();
125 | startServer();
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/mjl-jersey-server/src/test/java/de/codecentric/mjl/jerseytest/helpers/FilteringInMemoryTestContainerFactory.java:
--------------------------------------------------------------------------------
1 | package de.codecentric.mjl.jerseytest.helpers;
2 |
3 | import java.net.URI;
4 | import java.util.Set;
5 | import java.util.logging.Logger;
6 |
7 | import javax.ws.rs.core.UriBuilder;
8 |
9 | import com.sun.jersey.api.client.Client;
10 | import com.sun.jersey.api.client.config.ClientConfig;
11 | import com.sun.jersey.api.client.config.DefaultClientConfig;
12 | import com.sun.jersey.api.core.ResourceConfig;
13 | import com.sun.jersey.spi.container.WebApplication;
14 | import com.sun.jersey.spi.container.WebApplicationFactory;
15 | import com.sun.jersey.test.framework.AppDescriptor;
16 | import com.sun.jersey.test.framework.LowLevelAppDescriptor;
17 | import com.sun.jersey.test.framework.impl.container.inmemory.TestResourceClientHandler;
18 | import com.sun.jersey.test.framework.spi.container.TestContainer;
19 | import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
20 | import com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory;
21 |
22 | /**
23 | * A low-level test-container factory. Unlike {@link InMemoryTestContainerFactory}, this factory
24 | * does not override set filters and can thus be used to test resources where custom filters are
25 | * needed.
26 | *
27 | * @author michael.lex
28 | */
29 | public class FilteringInMemoryTestContainerFactory implements TestContainerFactory {
30 |
31 | @Override
32 | public Class supports() {
33 | return LowLevelAppDescriptor.class;
34 | }
35 |
36 | @Override
37 | public TestContainer create(URI baseUri, AppDescriptor ad) {
38 | if (!(ad instanceof LowLevelAppDescriptor))
39 | throw new IllegalArgumentException(
40 | "The application descriptor must be an instance of LowLevelAppDescriptor");
41 |
42 | return new FilteringInMemoryTestContainer(baseUri, (LowLevelAppDescriptor) ad);
43 | }
44 |
45 | private static class FilteringInMemoryTestContainer implements TestContainer {
46 |
47 | private static final Logger LOGGER = Logger.getLogger(FilteringInMemoryTestContainer.class
48 | .getName());
49 |
50 | final URI baseUri;
51 |
52 | final ResourceConfig resourceConfig;
53 |
54 | final WebApplication webApp;
55 |
56 | /**
57 | * Creates an instance of {@link FilteringInMemoryTestContainer}
58 | *
59 | * @param baseUri
60 | * URI of the application
61 | * @param ad
62 | * instance of {@link LowLevelAppDescriptor}
63 | */
64 | private FilteringInMemoryTestContainer(URI baseUri, LowLevelAppDescriptor ad) {
65 | this.baseUri = UriBuilder.fromUri(baseUri).build();
66 |
67 | LOGGER.info("Creating low level InMemory test container configured at the base URI "
68 | + this.baseUri);
69 |
70 | this.resourceConfig = ad.getResourceConfig();
71 | this.webApp = initiateWebApplication(resourceConfig);
72 | }
73 |
74 | @Override
75 | public Client getClient() {
76 | ClientConfig clientConfig = null;
77 | Set