See: org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
<mvc:annotation-driven/>
+
+ With XML annotation-driven works with org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
+ With Java annotations @EnableWebMvc does the same with org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
+
+ So annotation-driven and @EnableWebMvc are the same. The first one using XML files and the second one using Java annotations :/
+
+ All this stuff could be done by means of annotation-driven or @EnableWebMvc but in this way I have more control :/
-->
- <!-- Required for making work @ControllerAdvice and setting our custom return value handlers -->
- <mvc:annotation-driven>
- <mvc:return-value-handlers>
- <bean class="org.springframework.cloud.netflix.rx.SingleReturnValueHandler" />
- </mvc:return-value-handlers>
- </mvc:annotation-driven>
-
- <!--
- Instead of annotation-driven we could use @EnableWebMvc (Java code instead of XML files)
-
- If annotation-driven works with org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
- @EnableWebMvc does the same with org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
-
- Here I am using XML fiels intead of Java code :/
- -->
<context:annotation-config />
</util:list>
+ <bean id="singleReturnValueHandler" class="org.springframework.cloud.netflix.rx.SingleReturnValueHandler" />
<bean name="handlerAdapter"
- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
+ class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
</property>
<property name="messageConverters" ref="messageConverters" />
+ <property name="customReturnValueHandlers" ref="singleReturnValueHandler" />
+
<property name="requestBodyAdvice">
<util:list>
<bean id="requestBodyAdvice" class="org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice"/>
import java.util.ArrayList;
import java.util.List;
+import javax.inject.Inject;
+
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.domain.Page;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.spring.webservices.domain.Car;
import de.spring.webservices.rest.business.service.RxJavaBusinessLogic;
import rx.Observable;
+import rx.Subscriber;
+import rx.schedulers.Schedulers;
// jsonPath, how to: https://github.com/jayway/JsonPath | http://jsonpath.herokuapp.com/
-@Ignore
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath*:spring-configuration/mvc/rest/*.xml"})
public class RxJavaCarControllerIntegrationTest {
private static final int PAGE_SIZE = 10;
private static final String TEMPLATE = "Car: %s";
+ @Inject
+ private AsyncHandlerMethodReturnValueHandler singleReturnValueHandler;
+
private RxJavaBusinessLogic rxJavaBusinessLogic;
private RxJavaCarController controller;
private MockMvc mockMvc;
public void setup() {
rxJavaBusinessLogic = mock(RxJavaBusinessLogic.class);
controller = new RxJavaCarController(rxJavaBusinessLogic);
- mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
+ mockMvc = MockMvcBuilders
+ .standaloneSetup(controller)
+ .setCustomReturnValueHandlers(singleReturnValueHandler)
+ .build();
}
@Test
public void testWhenGetAllCarsThenRetrieveJsonValues() throws Exception {
final List<Car> cars = new ArrayList<>();
cars.add(new Car(1L, String.format(TEMPLATE, 1)));
- Observable<Page<Car>> observable = Observable.create(observer -> observer.onNext( new PageImpl<>(cars)));
+ Observable<Page<Car>> observable = Observable
+ .create((Subscriber<? super Page<Car>> observer) -> {
+ observer.onNext( new PageImpl<>(cars));
+ observer.onCompleted();
+ }).subscribeOn(Schedulers.io());
given(rxJavaBusinessLogic.findAll(new PageRequest(PAGE, PAGE_SIZE))).willReturn(observable);
MvcResult result = mockMvc.perform(get("/api/rxjava/cars/")
.accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(request().asyncStarted())
- .andExpect(request().asyncResult(instanceOf(Page.class)))
+ .andExpect(request().asyncResult(instanceOf(ResponseEntity.class)))
.andReturn();
mockMvc.perform(asyncDispatch(result))
@Test
public void testWhenGetOneCarThenRetrieveJsonValue() throws Exception {
- Observable<Car> observable = Observable.create(observer -> observer.onNext( new Car(1L, String.format(TEMPLATE, 1))));
+ Observable<Car> observable = Observable
+ .create((Subscriber<? super Car> observer) -> {
+ observer.onNext( new Car(1L, String.format(TEMPLATE, 1)));
+ observer.onCompleted();
+ }).subscribeOn(Schedulers.io());
given(rxJavaBusinessLogic.findById(1L)).willReturn(observable);
MvcResult result = mockMvc.perform(get("/api/rxjava/cars/{id}", 1L)
.accept(MediaType.APPLICATION_JSON_UTF8))
.andExpect(request().asyncStarted())
- .andExpect(request().asyncResult(instanceOf(Car.class)))
+ .andExpect(request().asyncResult(instanceOf(ResponseEntity.class)))
.andReturn();
mockMvc.perform(asyncDispatch(result))
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
}
+ // THIS GUY IS USING MY de.spring.webservices.rest.controller.adapters.RxJavaAdapter AND IT DOES NOT NEED to call onCompleted()
+ // I DO NOT THINK MY de.spring.webservices.rest.controller.adapters.RxJavaAdapter SHOULD BE USED. YOU'D BETTER USE THE spring netflix IMPLEMENTATION :/
@Test
public void testWhenCreateNewCarThenRetrieveJsonValue() throws Exception {
Car car = new Car(null, "nothing");