MockMvc body returns null body - spring-boot

EmployeeController.java
public ResponseEntity<?> getAddressByEmployeeId(String id, HttpServletRequest httpServletRequest) {
ResponseEntity<?> addressDTO = addressService.getAddressByEmployeeId(id);
System.out.println(addressDTO.getBody());
if (addressDTO.getBody()!= null) {
return new ResponseEntity<>(addressService.getAddressByEmployeeId(id), HttpStatus.OK);
} else {
System.out.println("*******************");
throw new GlobalException("No such id is found in db",null,604, httpServletRequest.getRequestURI(), false);
}
}
EmployeeControllerTest.java
WebMvcTest(EmployeeController.class)
class EmployeeControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private EmployeeService employeeService ;
// #InjectMocks
// private EmployeeController employeeController;
ObjectMapper objectMapper =new ObjectMapper();
ObjectWriter objectWriter=objectMapper.writer();
#Test
public void testtogetaddressbyEid() throws Exception {
AddressDTO addressDTO=new AddressDTO("1A1","Mogral house","Mogral","ksd","kerala");
String content=objectWriter.writeValueAsString(addressDTO);
// HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
HttpServletRequest mockRequest = mock(HttpServletRequest.class);
when(employeeService.getAddressByEmployeeId("1E1",mockRequest)).thenReturn(new ResponseEntity(addressDTO, HttpStatus.OK));
MockHttpServletResponse result=mockMvc.perform(MockMvcRequestBuilders
.get("/api/employees/1E1/address")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
assertThat(result.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(result.getContentAsString()).isEqualTo(
objectWriter.writeValueAsString(new ResponseEntity(addressDTO,HttpStatus.OK)));
}

Related

#Mock RestTemplate not returning expected value

I am creating unit test for my service class:
#Service
#Slf4j
public class SsaOpeningService {
#Autowired
private MockDataInitializer mockDataInitializer;
#Qualifier("restHttpsTemplateClient")
#Autowired
private RestTemplate restTemplate;
#Value("${acc-opening-casa.open-ssa}")
private String openSSAaccountUrl;
public CompletableFuture<AccountData> openSsa(
ApplicationDto items,
HttpHeaders headers,
BigInteger cifNo) {
log.info("Initializing headers");
HeaderRequest headerRequest = new HeaderRequest();
HttpHeaders header = headerRequest.initHeader(headers);
CurrentAcctReqBody request = CurrentAcctReqBody.builder()
.cifNo(cifNo)
.currencyType(SGD_CURRENCY)
.acName1(items.getApplicationData().getPersonalDetail().getName())
.productType(SSA_PRODUCT_CODE)
.noOfAccountHolders(BigInteger.ONE)
.accountType(ACC_TYPE)
.transactionRefNo(mockDataInitializer.randomIntInString(9))
.build();
log.info("Setting up entity for calling SSA opening.....");
HttpEntity<CurrentAcctReqBody> entity = new HttpEntity<>(request, header);
CurrentAcctResBody result = null;
try {
result = restTemplate
.postForObject(openSSAaccountUrl, entity, CurrentAcctResBody.class);
} catch (Exception e) {
log.info(e.getMessage());
}
System.out.println(14527);
System.out.println(result);
if(result !=null && result.getError()==null) {
AccountData accountData = AccountData.builder().build();
BeanUtils.copyProperties(result.getRbkAccountDetail(), accountData);
return CompletableFuture.completedFuture(accountData);
}
return null;
}
}
My test class:
#SpringBootTest
#RunWith(SpringRunner.class)
class SsaOpeningServiceTest {
#InjectMocks private SsaOpeningService ssaOpeningService;
#Autowired private MockDataInitializer dataInitializer;
#Mock private MockDataInitializer mockDataInitializer;
private static HttpHeaders headers = new HttpHeaders();
private static HeaderRequest ekycHeaderRequest = new HeaderRequest();
#BeforeAll
public static void init() {
headers = ekycHeaderRequest.initHeader();
}
#Qualifier("restHttpsTemplateClient")
#Mock private RestTemplate restTemplate;
#Test
void createSsa() throws IOException {
CurrentAcctResBody result = JSONUtils
.getObjectFromJson(DCResourceLoader.getResourceAsString("casa/ssa-res.json"), CurrentAcctResBody.class);
ApplicationDto items = ApplicationDto.builder().build();
Application application = dataInitializer.initialize();
BeanUtils.copyProperties(application, items);
when(restTemplate.postForObject(
any(String.class),
eq(HttpEntity.class),
eq(CurrentAcctResBody.class)))
.thenReturn(result);
System.out.println(1452);
System.out.println(result);
when(mockDataInitializer.randomIntInString(any(Integer.class)))
.thenReturn(dataInitializer.randomIntInString(9));
assertThat(ssaOpeningService.openSsa(items, headers, any(BigInteger.class))).isNull();
}
}
I have mocked my RestTemplate to return me the result I want. Problem is, it is not giving me the expected result. I have printed the result in both test class and service class. But in the service class it is always giving me null. I tried to give the most generic parameter when mocking but still doesnt work. The rest is working fine when running unit test EXCEPT for this part. Need assist on this. Thanks all!
#RunWith(MockitoJUnitRunner.class)
class SsaOpeningServiceTest {
#InjectMocks
private SsaOpeningService ssaOpeningService;
#Mock
private MockDataInitializer mockDataInitializer;
#Mock
private RestTemplate restTemplate;
#Test
void createSsa() throws IOException {
// some code
Mockito.when(restTemplate.postForObject(
nullable(String.class),
any(HttpEntity.class),
eq(CurrentAcctResBody.class)))
.thenReturn(result);
// some code
}
}

MockMvc response returns 404, expected response 201

I am new to unit testing REST API in Spring Boot.
I am expecting response status as CREATED but instead I am getting a PAGE NOT FOUND error.
Below is the code for:-
UserControllerUnitTests
#SpringBootTest
#ContextConfiguration(classes = { CommonConfig.class, SecurityConfig.class})
#RunWith(SpringRunner.class)
class UserControllerUnitTests {
private static ObjectMapper mapper;
private static final String URI = "/users";
MockMvc mvc;
#Autowired
WebApplicationContext webAppContext;
#Mock
UserService userService;
MvcResult mvcResult;
#BeforeAll
static void setUp() {
mapper = new ObjectMapper();
}
#BeforeEach
void initialize() throws Exception {
mvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
....
....
....
void shouldReturnStatusCreatedIfValidUserPassedForPostUser(long index) throws Exception {
int expectedStatus = HttpStatus.CREATED.value();
UserDAO returnUser;
UserDAO user = userList.get(index);
userList.remove(index);
String jsonContent = mapper.writeValueAsString(user);
user.setId(index);
user.setEncryptedPassword(null);
Mockito.when(userService.addUser(Mockito.any())).thenReturn(user);
mvcResult = mvc.perform(MockMvcRequestBuilders.post(URI)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(jsonContent)).andReturn();
//Mockito.verify(userService, Mockito.times(1)).addUser(Mockito.any());
int actualStatus = mvcResult.getResponse().getStatus();
Assert.assertEquals("Response status should be CREATED", expectedStatus, actualStatus);
jsonContent = mvcResult.getResponse().getContentAsString();
returnUser = mapper.readValue(jsonContent, UserDAO.class);
Assert.assertEquals("EncryptedPassword should not be returned", null,
returnUser.getEncryptedPassword());
}
User Controller.class
#RestController
#RequestMapping("users/")
public class UserController {
UserService userService;
#Autowired
public UserController(UserService userService) {
this.userService = userService;
}
....
....
....
#PostMapping(path = "",
consumes = { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON },
produces = { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public ResponseEntity<UserDAO> createUser(#Valid #RequestBody UserDAO user) {
String password = user.getEncryptedPassword();
user.setEncryptedPassword(null);
UserDAO retreivedUser;
if(user.getId() != 0)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
user.setEncryptedPassword(password);
retreivedUser = userService.addUser(user);
if(retreivedUser != null)
return new ResponseEntity<>(retreivedUser, HttpStatus.CREATED);
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
}
The full code can be found at https://github.com/vineethmaller/springboot-userservice
I spotted a few errors:
Get rid of ContextConfiguration
#SpringBootTest
// #ContextConfiguration(classes = { CommonConfig.class, SecurityConfig.class})
#RunWith(SpringRunner.class)
class UserControllerUnitTests {
Specify correct mapping on the controller (no slash)
#RestController
#RequestMapping("users")
public class UserController {
You setup your UserService mock which is not used in the test. Did you mean #MockBean?
#MockBean
UserService userService;

How to Mock ReloadableResourceBundleMessageSource in this case

I have a Rest controller class as shown below
#RestController
public class MyController {
#Autowired
private MYHelper myHelper;
#Autowired
#Qualifier("environmentMessageSource")
protected ReloadableResourceBundleMessageSource environmentMessageSource;
#PostMapping(value = {
employees
})
public #ResponseBody Map < String, Object > getEmployees(#RequestBody MyVO myvo) throws Exception {
Map < String, Object > responseMap = new HashMap < > ();
try {
responseMap = oeHelper.getDataService(environmentMessageSource.getMessage("MYPROP", null, null), myvo);
} catch (Exception e) {
}
return responseMap;
}
}
I am trying to write a Test Case for my controller . and its failing at ReloadableResourceBundleMessageSource
#RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {
private MockMvc mockMvc;
#Mock
private OEHelper myHelper;
#InjectMocks
private MyController myController;
#Mock
protected ReloadableResourceBundleMessageSource environmentMessageSource;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(myController)
.build();
environmentMessageSource.setCacheSeconds(0);
}
#Test
public void testgetESIDAndCalendarDates() throws Exception {
Map < String, Object > responseMap = new HashMap < > ();
MyVO myVO = new MyVO();
Mockito.when(messageSource.getMessage(Mockito.anyString(), Mockito.any(Object[].class), Mockito.any(Locale.class)))
.thenReturn("");
Mockito
.when(myHelper.getResponseFromService(Mockito.any(), Mockito.any(myVO.class)))
.thenReturn(responseMap);
mockMvc.perform(post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(myVO))
)
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
Its saying , it cannot find the key MYPROP in environpropertiesfile for locale null
org.springframework.context.NoSuchMessageException: No message found under code 'MYPROP' for locale 'null'.

Update Question: How to Mock MapToJson Class

this is an update to my previous question. I have a Utility class which I already manage to cover with my unit test except when the condition returns false.
Here is my class:
#Component
public class Utils {
#Autowired
private ObjectMapper mapper = new ObjectMapper();
#Autowired
private LoggingService loggingService;
public <E> String mapToJsonString(E object) {
try {
if (object == null) {
throw new IOException(ErrorMessage.ERROR_PROCESSING_JSON_NULL);
}else {
return mapper.enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(object); //NullPointer Here
}
} catch (IOException e) {
loggingService.logError(this.getClass().getName(), "1", ErrorMessage.ERROR_MAPPING_TO_JSONSTRING, e);
return "";
}
}
}
and here is my unit test
#RunWith(SpringRunner.class)
#ContextConfiguration(classes = ATMMonitoringApplication.class, initializers = ConfigFileApplicationContextInitializer.class)
public class ObjectToJsonStringTest {
#SpyBean
private ATM atm;
#Autowired
private Utils utils;
#MockBean
private ObjectMapper mapper;
#MockBean
private LoggingService loggingService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
myModelClass = new MyModelclass();
myModelClass.setStatus("U");
myModelClass.setTermCode("001");
myModelClass.setLocation("BGC");
}
#Test
public void testObjectToJson() throws JsonProcessingException {
String output = utils.mapToJsonStringmyModelClass
assertNotNull(output);
}
#Test
public void testObjectToJsonNull() throws JsonProcessingException {
String output = utils.mapToJsonString(null);
assertNull(output);
}
#Test
public void testJsonParsingException() {
myModelClass = new MyModelclass();
myModelClass = null;
String output = utils.mapToJsonString(myModelClass);
Mockito.when(loggingService.logError(this.getClass().getName(), "1", ErrorMessage.ERROR_MAPPING_TO_JSONSTRING, new Exception()))
.thenReturn("");
assertThat(output).isEmpty();
}
}
Stack trace says that i have a null pointer on this line of code:
return mapper.enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(object);
Please help me on this. Thanks
Solved it. I just change this
#Mock
private ObjectMapper mapper;
From #MockBean and it covered the whole class.

Spring tests - mock returns null

I have a small issue with mocking methods . Where mock should return an predefined object, it returns null. here is test set up:
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserControllerTest {
#Autowired
WebApplicationContext webContext;
#MockBean
UserTransferService userTransferService;
#MockBean
UserService userService;
MockMvc mockMvc;
private User user = DummyObjects.getDummyUser();
private User modifiedUser = DummyObjects.getModifiedUser();
private UserTO userTO = DummyObjects.getDummyUserTO();
private UserTO modifiedUserTO = DummyObjects.getModifiedUserTO();
#Before
public void setUp() throws Exception {
List<User> users = new ArrayList<>();
users.add(modifiedUser);
users.add(user);
given(this.userTransferService.getTO(user)).willReturn(userTO);
given(this.userTransferService.getObject(userTO)).willReturn(user);
given(this.userTransferService.getTO(modifiedUser)).willReturn(modifiedUserTO);
given(this.userTransferService.getObject(modifiedUserTO)).willReturn(modifiedUser);
given(this.userService.findAll()).willReturn(users);
given(this.userService.save(user)).willReturn(user);
given(this.userService.removeById(1)).willReturn(true);
given(this.userService.getById(1)).willReturn(user);
given(this.userService.getById(2)).willReturn(null);
given(this.userService.modify(modifiedUser)).willReturn(modifiedUser);
given(this.userService.findByLogin(user.getLogin())).willReturn(user);
given(this.userService.findByLogin("AAA")).willReturn(null);
mockMvc = MockMvcBuilders
.webAppContextSetup(webContext)
.apply(springSecurity())
.build();
}
test itself:
#Test
public void shouldAddUser() throws Exception {
mockMvc.perform(post("/api/user")
.content(TestingUtility.asJsonString(userTO))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.with(csrf().asHeader()))
.andExpect(status().is(200))
.andExpect(content().json(TestingUtility.asJsonString(userTO)));
}
and Controller method:
#RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public UserTO modifyUser(#RequestBody UserTO userTO, UsernamePasswordAuthenticationToken principal) throws IllegalAccessException{
User user = userTransferService.getObject(userTO);
if (principal.getName().equals(userTO.getLogin()) || permissionService.hasPermission(principal,Permission.SU)) {
return userTransferService.getTO(userService.modify(user));
} else {
throw new IllegalAccessException("You are not allowed to modify user");
}
}
User is null, but UserTO is filled. So mocked method UserTransferService.getObject(userTO) is not working properly.

Resources