I am trying to mock RestTemplate but I when debugging I see the error bellow, which produces a null pointer:
Method threw 'org.mockito.exceptions.misusing.UnfinishedStubbingException' exception. Cannot evaluate org.springframework.http.ResponseEntity$$EnhancerByMockitoWithCGLIB$$3c63496d.toString()
This is the line of code that I am trying to test :
ResponseEntity<EmailEntity[]> response =
restTemplate.exchange(apiURI, HttpMethod.GET, entity, EmailEntity[].class);
EmailEntity[] partialEmailEntity = response.getBody();
response.getBody() returns a null.
This is a piece of code in my test :
#RunWith(MockitoJUnitRunner.class)
public class EmailItemReaderTest {
#Mock
private RestTemplate restTemplate;
#InjectMocks
private EmailItemReader reader;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}
...
...
ResponseEntity<EmailEntity> mockEntity = Mockito.spy(new ResponseEntity(mockObject, HttpStatus.OK));
doReturn(mockEntity).when(restTemplate).exchange(
Mockito.any(URI.class),
Mockito.any(HttpMethod.class),
Mockito.any(HttpEntity.class),
EmailEntity[].class);
reader.read();
Related
I am trying to test my REST endpoints using RestAssured with mocking some of the service/repositories in the controller.
this is my test class:
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {VedicaConfig.class})
#AutoConfigureMockMvc
#ActiveProfiles("test")
public class RESTTest {
#LocalServerPort
private int port;
#Autowired
private MockMvc mvc;
#Mock
MetaVersionDAO metaVersionDAO;
#InjectMocks
DocCtrl docCtrl;
#Before
public void contextLoads() {
RestAssured.port = port;
assertThat(mvc).isNotNull();
// this must be called for the #Mock annotations above to be processed.
MockitoAnnotations.initMocks(this);
RestAssuredMockMvc.standaloneSetup(MockMvcBuilders.standaloneSetup(docCtrl));
}
#Test
public void shouldGetThumbnail() {
String ver = "1.0";
String uuid = "124-wqer-365-asdf";
when(metaVersionDAO.getMetaByVersionUUID(ver, uuid)).thenReturn(new DocVersion());
given()
.when()
.param("uuid", uuid)
.param("versionVed", ver)
.get(CTX_BASE + "/thumbnail")
.then()
.log().ifValidationFails()
.statusCode(OK.value())
.contentType(ContentType.BINARY);
}
}
now, the REST endpoint itself is being hit correctly with supplied parameters. this endpoint has DocCtrl injected which uses metaVersionDAO instance in turn:
public RawDocument getDocThumbnail(String uuid, String versionVed) throws Exception {
DocVersion docVersion = metaVersionDAO.getMetaByVersionUUID(versionVed, uuid);
InputStream inputStream = okmWebSrv.getOkmService().getContentByVersion(uuid, versionVed);
String dataType = docVersion.getMetadata().getAdditionals().get(Vedantas.CONTENT_TYPE);
ByteArrayInputStream bais = new ByteArrayInputStream(createPDFThumbnail(dataType, inputStream));
RawDocument rawDocument = new RawDocument(bais, "qwer");
return rawDocument;
}
as you can see, I have tried to mock metaVersionDAO at the top of the #Test method so I expected it to return new DocVersion() as I set it to, but in this DAO the actual code is being called and it fails on entityManager which is null.
My question is why metaVersionDAO.getMetaByVersionUUID doesn't return my mocked object and what should I do to make it so?
spring-mock-mvc: 3.3.0
spring-boot: 2.1.2.RELEASE
Thanks!
solved by changing #Mock for #MockBean.
so it is:
#MockBean
MetaVersionDAO metaVersionDAO;
everything else remains the same as in the post and it uses mocked instance.
I have a Circuit breaker implemented which works fine when I run it (meaning the fallback method is run whenever the RestTemplate receives an HTTP status code between 400 and 599). However, when I try to unit test this fallback, by returning a Bad Request (HTTP 400) the fallback method is not invoked. Why is this?
Snippet from class:
class Test {
#Autowired
private RestTemplate restTemplate;
#HystrixCommand(fallbackMethod = "fallback")
public void test() {
HttpEntity<Object> testRequest = new HttpEntity<>();
ResponseEntity<String> response = restTemplate.exchange(
"http://localhost:8080/testurl",
HttpMethod.POST,
testRequest,
String.class);
}
private void fallback() {
System.out.println("Fallback method called");
}
}
Snippet from test class
#MockBean
private RestTemplate mockRestTemplate;
#Autowired
Test test;
#Test
public void testRestTemplateReturning400() {
ResponseEntity<String> response = new ResponseEntity<>(HttpStatus.BAD_REQUEST);
when(mockRestTemplate.exchange(anyString(), any(), any(), eq(String.class))).thenReturn(response);
test.test();
verify(mockRestTemplate, times(1)).exchange(anyString(), any(), any(), eq(String.class));
}
Add
#EnableCircuitBreaker
#EnableAspectJAutoProxy
to your test configuration
I am trying to write a unit test for spring controller, the myService class is autowired in myController,I have mocked myService class but when I debug the code it is coming null
myService = null
I am not able to inject this service for my controller.
#RunWith(MockitoJUnitRunner.class)
public class TestManageDevices {
private MockMvc mockMvc;
#Mock
MyService myService;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new MyController())
.build();
}
#Test
public void shouldPass() throws Exception {
Mockito.doNothing().when(myService).someMethod(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
JobResponse jobResponse = JobResponse.builder().responseCode(0).build();
jobResponse.requestObj = "mockedStringObject";
RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/pathfortest")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.param("id", Mockito.anyString());
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
System.out.println(result.getResponse().getContentAsString());
MockHttpServletResponse response = result.getResponse();
Assert.assertEquals(HttpStatus.CREATED.value(), response.getStatus());
}
}
You are newing up the controller manually with new MyController() in the setUp method, so dependencies are not being injected.
Create a variable of type controller
#InjectMocks
MyController myController;
Use this when creating mockMVC instance in your setUp method as below:
mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
This should work.
I am attempting to write a unit test for a generic service class like the following:
public class ApiService{
private RestTemplate restTemplate;
private ServiceDao serviceDao;
#Autowired
public ApiService(RestTemplate restTemplate, ServiceDao serviceDao) {
this.restTemplate = restTemplate;
this.serviceDao = serviceDao;
}
public ResponseEntity getObject(ObjectRequest request) {
// Service logic here
}
public ResponseEntity postObject(CreateObjectRequest request) {
// Service logic here
}
}
But am struggling with how to mock the restTemplate in the constructor of my service class such that when the test runs, data is not persisted.. I've looked into Mockito though don't see many examples or documentation regarding Mockito + TestNG in this context. Any help would be appreciated
First of all - if possible inject RestOperations in your service instead of RestTemplate. Then you will be able easily mock its behavior (note: RestTemplate implements RestOperations).
If using RestOperations is not possible - you can do something this:
RestTemplate myTemplate = Mockito.spy(new RestTemplate());
String expectedOutput = "hello mock";
String inputUrl = "https://stackoverflow.com/questions/53872148/unit-test-service-class-with-mocks-using-testng";
Mockito.doReturn(expectedOutput).when(myTemplate).getForObject(inputUrl, String.class);
String result = myTemplate.getForObject(inputUrl, String.class);
Assert.assertEquals(expectedOutput, result);
I've actually constructed a method using Mockito as follows... there might be a more elegant solution so I would be interested to see:
public class ServiceTest {
#BeforeMethod(groups="serviceTest")
public void beforeMethod() {
MockitoAnnotations.initMocks(this);
}
#Test(groups="serviceTest")
public void testGetService_returns200() {
when(serviceDao.getService(any(String.class), any(RestTemplate.class), any(HttpHeaders.class))).thenReturn(new ResponseEntity(new Object(), HttpStatus.OK));
ObjectRequest request = new ObjectRequest();
// set request values
ResponseEntity testResponse = apiService.getObject(request);
}
}
I am trying to test a RestTemplate exchange with a response entity in a controller from a rest Service in another application. My Junit test is coming back with a null ResponseEntity. I have tried a couple ways with no luck. First tried using mockito to mock response methods (when...then). Second tried with Exchange matchers. I also tried to mix the two with no luck. Any help would be great. Here is my Controller response I am creating:
ResponseEntity<RestResult<List<SiteMessage>>> response = rest.exchange(getAllMessagesUrl, HttpMethod.GET,
HttpEntity.EMPTY, new ParameterizedTypeReference<RestResult<List<SiteMessage>>>() {
});
Here is my Junit Test:
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest
public class MessageControllerTests {
#InjectMocks
MessageController messageController;
#Mock
RestTemplate restTemplate;
#Mock
SiteMessageService serviceMock;
#Mock
ResponseEntity<RestResult<List<SiteMessage>>> response;
private MockMvc mockMvc;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(messageController).build();
}
#Test
public void testListPage() throws Exception {
RestResult<List<SiteMessage>> result = new RestResult<>();
result.setMessage("success");
SiteMessage message1 = new SiteMessage();
SiteMessage message2 = new SiteMessage();
message1.setId("ldsf030j2ldjs");
message2.setId("ldsf0432234s");
List<SiteMessage> messageList = new ArrayList<>();
messageList.add(message1);
messageList.add(message2);
result.setResults(messageList);
when(response.getBody()).thenReturn(result);
when(response.getStatusCode()).thenReturn(HttpStatus.NOT_FOUND);
when(restTemplate.exchange(
Matchers.any(URI.class),
Matchers.eq(HttpMethod.GET),
Matchers.any(),
Matchers.<ParameterizedTypeReference<RestResult<List<SiteMessage>>>>any())
).thenReturn(response);
mockMvc.perform(get("/message/list")).andExpect(status().isOk()).andExpect(view().name("message/list"));
}
}
I am trying to return a response with a body containing a RestResult object, which has a list of messages and a message