public class ServiceTest {
@Mock
RestTemplate restTemplate = new RestTemplate();
@InjectMocks
Service service = new Service();
ResponseEntity responseEntity = mock(ResponseEntity.class);
@Test
public void test() throws Exception {
Mockito.when(restTemplate.getForEntity(
Mockito.anyString(),
Matchers.any(Class.class)
))
.thenReturn(responseEntity);
boolean res = service.isEnabled("something");
Assert.assertEquals(res, false);
}
J'ai essayé de tester un test simple pour un service incluant un restclient. Il semble que je n’ai pas moqué la RestTemplate
avec succès. Il semble que le code obtienne les données réelles et non les données factices. Tout le monde peut m'aider avec ça.
Le service lui-même ressemblera à ceci:
public class Service{
public boolean isEnabled(String xxx) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
Le problème est que dans votre isEnabled
, vous créez un nouveau RestTemplate. Cela est faux pour deux raisons. La première est que vous ne pouvez pas vous moquer de cette carte puisque vous en créez une nouvelle. Deuxièmement, il est bon d'éviter de créer de nouveaux objets par requête. RestTemplate est thread-safe et peut donc être un membre de la classe de service, utilisé par plusieurs threads.
Changez votre classe de service en quelque chose comme ceci:
public class Service{
RestTemplate restTemplate = new RestTemplate();
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
Maintenant que votre RestTemplate est devenu un membre du groupe, vous pouvez maintenant vous moquer de l'une des deux manières suivantes. Tout d'abord, injectez-le à l'aide du @InjectMock
ou utilisez une méthode de définition que vous appelez à partir de votre test.
Puisque vous utilisez InjectMock dans votre code, nous pouvons continuer avec cela.
@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
@Mock
RestTemplate restTemplate;
@InjectMocks
@Spy
Service service;
ResponseEntity responseEntity = mock(ResponseEntity.class);
@Test
public void test() throws Exception {
Mockito.when(restTemplate.getForEntity(
Mockito.anyString(),
ArgumentMatchers.any(Class.class)
))
.thenReturn(responseEntity);
boolean res = service.isEnabled("something");
Assert.assertEquals(res, false);
}
Notez que j'ai fait quelques changements. Premièrement, j'ai supprimé les new RestTemplate()
et new Service()
. Vous devriez laisser Mockito les créer pour vous. En les annotant avec @Mock
et @Spy
, vous vous assurerez que Mockito les créera pour vous et, plus important encore, injectera les imitations dans votre objet service
.
La structure de test de Spring MVC propose la classe MockRestServiceServer
pour le code de service RESTful des tests unitaires.
Voici un tutorial sur son utilisation.
Si vous utilisez @Autowired, vous pouvez utiliser MockRestServiceServer . L'exemple ci-dessous est l'exemple.
@Service
public class Service{
@Autowired
private RestTemplate restTemplate;
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
@Service doit utiliser @Autowired pour créer un objet automatiquement.