JUnit: Impossible de se moquer de l'RestTemplate objet à appeler postForObject méthode
Je suis nouveau sur Mockito ainsi que le Printemps est RestTemplate. Je suis en train de travailler sur JUnit tests pour une fonctionnalité qui envoie une requête à un service web et obtient la réponse grâce à l'utilisation de RestTemplate. Je veux que le serveur de répondre avec une réponse que je veux donc que je peux tester les fonctionnalités de base de cette réponse. Je suis à l'aide de Mockito de se moquer.
Je ne suis pas sûr de l'endroit où je vais mal. Je ne suis pas à la création de bon se moque ? Id de mon objet JSON mappeur pas été configuré correctement ?
Fichier de Configuration définissant le RestTemplate bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="xsStreamMarshaller" />
<property name="unmarshaller" ref="xsStreamMarshaller" />
</bean>
</list>
</property>
</bean>
<bean id="xsStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"></bean>
</beans>
Mon DTO:
import org.codehaus.jackson.annotate.JsonWriteNullProperties;
@JsonWriteNullProperties(false)
public abstract class BaseDTO {
protected boolean error;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
}
public class ChildDTO extends CommercialBaseDTO {
private String fullName;
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
}
Classe contenant la méthode de test:
package com.exmpale.mypackage;
import org.springframework.web.client.RestTemplate;
@Component
public class MyUtilClass {
@Autowired
private RestTemplate restTemplate;
public RestTemplate getRestTemplate(){
return restTemplate;
}
public void setRestTemplate(RestTemplate restTemplate){
this.restTemplate = restTemplate;
}
//Method to test
public ChildDTO getChildDTO(MyUser myUser, HttpServletRequest request, HttpServletResponse response)
{
response.setContentType("application/json");
//Nothing much here, it takes the myUser and convert into childDTO
ChildDTO childDTO = new MyUtilClass().getDTOFromUser(request, myUser);
//This is the restTemplate that iam trying to mock.
childDTO = restTemplate.postForObject("http://www.google.com", childDTO, ChildDTO.class);
if (childDTO.isError()) {
//Then do some stuff.........
}
return childDTO;
}
}
La classe de test JUnit
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"test-config.xml"})
public class MyUtilClassTest {
@InjectMocks
RestTemplate restTemplate= new RestTemplate();
private MockRestServiceServer mockServer;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
//Creating the mock server
//Add message conveters
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new FormHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new MappingJacksonHttpMessageConverter());
//Create Object mapper
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure( DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure( SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure( SerializationConfig.Feature.AUTO_DETECT_FIELDS, true);
objectMapper.configure( SerializationConfig.Feature.AUTO_DETECT_GETTERS,true);
objectMapper.configure( SerializationConfig.Feature.AUTO_DETECT_IS_GETTERS,true);
MappingJacksonHttpMessageConverter jsonMessageConverter = new MappingJacksonHttpMessageConverter();
jsonMessageConverter.setObjectMapper(objectMapper);
messageConverters.add(jsonMessageConverter);
//Set the message converters
restTemplate.setMessageConverters(messageConverters);
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void testGetChildDTO()throws Exception {
MyUtilClass myUtil = new MyUtilClass();
MyUser myUser = new MyUser();
HttpServletRequest request = new HttpServletRequestWrapper(new MockHttpServletRequest());
HttpServletResponse response = new HttpServletResponseWrapper(new MockHttpServletResponse());
//create the mocks for ChildDTO. I want MyUtilClass().getDTOFromUser(request, myUser) to return this.
ChildDTO childDTOMock_One = Mockito.mock(ChildDTO);
//Want this to be returned when restTemplate.postForObject() is called.
ChildDTO childDTOMock_Two = Mockito.mock(ChildDTO.class);
childDTOMock_Two.setError(false);
//create the mocks for userMgntUtils
MyUtilClass myUtilClassMock = Mockito.mock(MyUtilClass.class);
//stub the method getDTOFromUser() to return the mock object. I need this mock to be passed to 'postForObject()'
Mockito.when(myUtilClassMock.getDTOFromUser(request, myUser)).thenReturn(childDTOMock_One);
String responseJSON="{\"error\":false}";
//set the expectation values for mockServer
mockServer.expect( requestTo("http://www.google.com")).andExpect(method(HttpMethod.POST)).andRespond(withSuccess(responseJSON,MediaType.APPLICATION_JSON));
//set the expectation values for restTemplate
Mockito.when(restTemplate.postForObject( "http://www.google.com", childDTOMock_One, ChildDTO.class)).thenReturn(childDTOMock_Two);
TypedUserDTO result = userMgmtUtils.getUserProfileDTO(registerUser, request, response, action);
assertNotNull(result);
}
}
L'obtention de l'exception suivante:
org.springframework.http.convertisseur de.HttpMessageNotWritableException:
Ne pouvait pas écrire JSON: Aucun processus trouvé pour la classe
org.mockito.interne.stubbing.defaultanswers.GloballyConfiguredAnswer
et pas de propriétés découvertes pour créer BeanSerializer (pour éviter
exception, désactiver SerializationConfig.Fonctionnalité.FAIL_ON_EMPTY_BEANS) )
(à travers la chaîne de référence:
com.biogenidec.dto.TypedUserDTO$$EnhancerByMockitoWithCGLIB$$bee3c447["callbacks"]->org.mockito.internal.creation.MethodInterceptorFilter["handler"]->org.mockito.internal.handler.InvocationNotifierHandler["mockSettings"]->org.mockito.internal.creation.settings.CreationSettings["defaultAnswer"]);
exception imbriquée est org.codehaus.jackson.carte.JsonMappingException: Aucun
sérialiseur trouvé pour la classe
org.mockito.interne.stubbing.defaultanswers.GloballyConfiguredAnswer
et pas de propriétés découvertes pour créer BeanSerializer (pour éviter
exception, désactiver SerializationConfig.Fonctionnalité.FAIL_ON_EMPTY_BEANS) )
(à travers la chaîne de référence:
com.biogenidec.dto.TypedUserDTO$$EnhancerByMockitoWithCGLIB$$bee3c447["callbacks"]->org.mockito.internal.creation.MethodInterceptorFilter["handler"]->org.mockito.internal.handler.InvocationNotifierHandler["mockSettings"]->org.mockito.internal.creation.settings.CreationSettings["defaultAnswer"])
Et:
Caused by: org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.mockito.internal.stubbing.defaultanswers.GloballyConfiguredAnswer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.biogenidec.dto.TypedUserDTO$$EnhancerByMockitoWithCGLIB$$bee3c447["callbacks"]->org.mockito.internal.creation.MethodInterceptorFilter["handler"]->org.mockito.internal.handler.InvocationNotifierHandler["mockSettings"]->org.mockito.internal.creation.settings.CreationSettings["defaultAnswer"])
OriginalL'auteur Ash Ash | 2014-05-20
Vous devez vous connecter pour publier un commentaire.
L'idée de Mockito est à l'épreuve de la classe et aucun des dépendances à l'extérieur. Donc, si votre test
MyUtilClass
vous voulez vous moquer de laRestTemplate
classe. Et votre @InjectMocks est sur la mauvaise classe voir ci-dessous.Aussi je trouve d'une mauvaise pratique pour tester d'autres cadres de classes, plus souvent alors pas, ils ont déjà testé leur classe et votre duplication de leur travail.
Vous pouvez poster votre vite plz
OriginalL'auteur ndrone
Comme souligné ci-dessus, pour tester votre méthode avec mockito, il n'est pas nécessaire d'initialiser restTemplate.
Il suffit de vérifier que les paramètres d'entrée sont corrects (si nécessaire) et de renvoyer la bonne moqueur objet de restTemplate.
Nous n'avons pas tester le restTemplate ici, nous ne tester notre code. C'est l'objet de tests unitaires.
Vous pouvez faire quelque chose comme cela, ou quelque chose de plus simple:
OriginalL'auteur Serg Rubtsov