I have a put method, which takes an "Accept" header with value "application/json", and a requestBody class, and returns a ResponseEntity class. Can anyone tell me how to write tests for this method
This is my put api
public ResponseEntity<String> registerUserUsingPUT(#Parameter(in = ParameterIn.DEFAULT, description = "", schema=#Schema()) #Valid #RequestBody UserInput body) {
String accept = request.getHeader("Accept");
if (accept != null && accept.contains("application/json")) {
UserInfo user = userInfoService.getByEmail(body.getEmail());
if(user==null) {
user = new UserInfo();
String email = body.getEmail();
if(email.matches("^[a-z0-9._%+-]+#[a-z0-9.-]+.[a-z]{2,4}$")) user.setEmail(email);
user.setFirstName(body.getFirstName());
user.setLastName(body.getLastName());
user.setPassword(body.getUserPassword());
user.setRole(roleService.findRoleByType("Customer"));
if(body.getPhoneNo().length()==10) user.setPhoneNumber(body.getPhoneNo());
else return new ResponseEntity<String>("Incorrect Phone number",HttpStatus.BAD_REQUEST);
user.setPoints(0);
user.setStatus("Active");
user.setWalletBalance(0);
AddressDetails address = new AddressDetails();
address.setAddress(body.getAddress());
String pincode = body.getPinCode();
if(pincode.matches("^[0-9]{1,6}$")) address.setPincode(pincode);
address.setUser(user);
userInfoService.register(user);
addressDetailsDao.save(address);
return new ResponseEntity<String>("Registered",HttpStatus.OK);
}
else {
return new ResponseEntity<String>("User Already Exists",HttpStatus.BAD_REQUEST);
}
}
return new ResponseEntity<String>(HttpStatus.NOT_IMPLEMENTED);
Related
Please help the beginner.
When sending a request to the requestBody json I get:
key: "{
"grant_type" : "client_credentials",
"client_id" : "OC_CLIENT_ID",
"client_secret" : "OC_CLIENT_SECRET"
}"
value: ""
and it is required that the requestBody looks like this
{
key:"grant_type"
value: "client_credentials"
}
{
key:"client_id"
value: "OC_CLIENT_ID"
}
{
key:"client_secret"
value: "OC_CLIENT_SECRET"
}
The server sent for some reason not a set of parameters, but simply stuck json into the name of the first parameter.
The code is:
#Path("/")
public interface OAuth2RequestService {
#POST
AccessTokenRecord create(#HeaderParam(value = "Content-type") String type,
#FormParam(value = "grant_type") String grantType,
#FormParam(value = "client_id") String clientId,
#FormParam(value = "client_secret") String clientSecret);
}
#Override
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public OAuth2Interceptor getAccessTokenInterceptor(Account account,
Boolean isGeneralEpaService) {
if (openAmIsEnabled(account)) {
final FeignOptions<OAuth2RequestService> options =
new FeignOptions<>(getAccessTokenUrl(account, isGeneralEpaService));
final AccessTokenRecord accessTokenRecord = workerRestService(options)
.create(HEADER_TYPE, CLIENT_CREDENTIALS, getClientId(isGeneralEpaService),
getClientSecret(isGeneralEpaService));
logger.infof("OAuth2 access token retrieval succeeded.");
return new OAuth2Interceptor(accessTokenRecord);
}
final AccessTokenRecord accessTokenRecord = new AccessTokenRecord();
accessTokenRecord.setAccessToken(getOsDefaultAccessToken(account));
accessTokenRecord.setTokenType(TOKEN_TYPE);
return new OAuth2Interceptor(accessTokenRecord);
}
private OAuth2RequestService workerRestService(
final FeignOptions<OAuth2RequestService> options) {
final Request.Options requestOptions =
new Request.Options(options.getConnectionTimeOut(), options.getReadTimeOut());
return Feign.builder().options(requestOptions).client(new OkHttpClient())
.contract(new JAXRSContract()).encoder(new JacksonEncoder())
.decoder(new JacksonDecoder()).decode404()
.target(OAuth2RequestService.class, options.getHostUrl());
}
I have tried several options with #QueueParam #FormParam
I want to update my user profile if the String loginExist = null or loginExist.equals(principal.getName())
the problem is that I get NullPointerException.
this is my code:
// update profile
#RequestMapping(value = "/updateRH", method = RequestMethod.POST)
public ModelAndView updateRH(Principal principal, #ModelAttribute("user") user user) {
ModelAndView mv = new ModelAndView();
String loginExist = "";
user rh = RhRepo.findByUsername(principal.getName());
try {
loginExist = userRepo.findCountUsername(user.getUsername());
} catch (Exception e) {
}
System.out.println(loginExist);
if (loginExist.equals(null) || loginExist.equals(principal.getName())) {
user.setId(RhRepo.findByUsername(principal.getName()).getId());
user.setPwd(encoder.encode(user.getPwd()));
RhRepo.save(user);
} else {
String msg = "Username Deja exist !!!";
mv.addObject("msg", msg);
}
mv.addObject("rh", rh);
mv.setViewName("rhprofile");
return mv;
}
loginExist.equals(null) will throw NPE if loginExist is null as you are trying to call a method from a null object.
Use :-
loginExist == null
instead.
So the problem is user.getUsername(). the user is null and trying to get its username causes a NullPointerWxception.
add a check before that call, try this:
if (user != null) {
loginExist = userRepo.findCountUsername(user.getUsername());
}
otherwise (if it is null), you need to create the user before trying to find it from repository.
I am trying to mock a constructor 'EmailParams' in my test class.
Mocking is failing since the constructor EmailParams mocks as null.
Below is my test method
#Test
public void getContactEmailsByFilterSuccessTest() throws Exception {
String contactId = "752";
String emailAddress = "test#gmail.com";
String emailType = "EW";
MockHttpServletRequest request = new MockHttpServletRequest();
when(helper.isNumeric(any(String.class))).thenReturn(true);
List<ContactXref> sourcedContacts = getContactXrefs();
when(contactXrefServiceMock.getContactsForId(contactId)).thenReturn(sourcedContacts);
EmailParams emailParams = new EmailParams("test#gmail.com", "EW", sourcedContacts.get(0).getContact().getContactId().toString());
List<Email> emailsList = getEmailsList();
when(emailServiceMock.getEmailByFilter(emailParams)).thenReturn(emailsList);
ResponseEntity<List<Email>> response = contactControllerMock.getContactEmailsByFilter(request, contactId, emailAddress, emailType);
Assert.assertEquals("getContactEmailsByFilterSuccessTest: Expected response code to be 200", "200",
response.getStatusCode().toString());
}
This is the method I am trying to mock. Test fails when its trying to mock the constructor
#GetMapping(value = "/{contactId}/" + UrlMapping.EMAILS, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Email>> getContactEmailsByFilter(HttpServletRequest request,
#PathVariable(name = RequestParams.CONTACTID) String contacId,
#RequestParam(required = false, name = RequestParams.EMAILADDRESS) String emailAddress,
#RequestParam(required = false, name = RequestParams.EMAILTYPE) String emailType)
throws Exception {
ResponseEntity response = new ResponseEntity("Only numeric contactId is allowed", HttpStatus.BAD_REQUEST);
List<Email> emailList;
List<ContactXref> sourcedContacts;
if (helper.isNumeric(contactId)) {
sourcedContacts = contXrefService.getContactsForId(contactId);
EmailParams params = new EmailParams(emailAddress, emailType, sourcedContacts.get(0).getContact().getContactId().toString());
emailList = emailService.getEmailByFilter(params);
if (emailList != null) {
response = emailList.size() == 0 ? new ResponseEntity("No emails were found for the request", HttpStatus.NOT_FOUND) : new ResponseEntity(emailList, new HttpHeaders(), HttpStatus.OK);
} else {
response = new ResponseEntity("Encountered exception in retrieving emails", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
return response;
}
Here is my class which has the constructor.
public class EmailParams {
String email;
String emailType;
String ptyId;
public EmailParams() {
super();
}
public EmailParams(String pEmail, String pEmailType, String pPtyId) {
email = pEmail;
emailType = pEmailType;
ptyId = pPtyId;
}
}
How to mock it properly? thanks in advance.
If the equals method is not overridden in EmailParams class by default Mockito uses Object.equals to compare the EmailParams passed to getEmailByFilter method. In your case both object properties have same values but still they are different objects. So either override the equals method in EmailParams or
use ArgumentMatchers.argThat
when(emailServiceMock.getEmailByFilter(ArgumentMatchers.argThat(p -> p.getPEmail().equals("test#gmail.com") && condition2 && condition3 )))
.thenReturn(emailsList);
So emailService is expected to be invoked with emailParams. The emailParams is constructed using emailAddress, emailType and a contactId. If you look closely, you'll realize that sourcedContacts in your controller is the result of contXrefService.getContactsForId(contactId).
Why is this a problem? Well, look at this line in your test:
when(contactXrefServiceMock.getContactsForEcmId(contactId)).thenReturn(sourcedContacts)
You're mocking getContactsForEcmId to return the sourcedContacts. Instead, you should be mocking getContactsForId.
As shown in the image, it says "Response Class (Status 200)" for the add operation. However, the add operation has been implemented in such a way that it will never return 200. It returns 201 on success.
My question is how can I change the (Status 200) to (Status 201)?
The code for this part is as follows:
#RequestMapping(method = RequestMethod.PUT, value = "/add")
#ApiOperation(value = "Creates a new person", code = 201)
#ApiResponses(value = {
#ApiResponse(code = 201, message = "Record created successfully"),
#ApiResponse(code = 409, message = "ID already taken")
})
public ResponseEntity<String> add(#RequestParam(value = "name", required = true) String name,
#RequestParam(value = "id", required = true) String id) {
if (PD.searchByID(id).size() == 0) {
Person p = new Person(name, id);
PD.addPerson(p);
System.out.println("Person added.");
return new ResponseEntity<String>(HttpStatus.CREATED);
} else {
System.out.println("ID already taken.");
return new ResponseEntity<String>(HttpStatus.CONFLICT);
}
}
Thanks!
You can add the #ResponseStatus annotation to any a controller method to define the http status it should return. Ex
Adding the following annotation on acontroller method:
#ResponseStatus(code = HttpStatus.CREATED)
Will return a HTTP status 201 (Created)
Adding the following annotation in controller method (method = requestMethod.PUT) or (method = requestMethod.POST)
#ResponseStatus (code = HttpStatus.ACCEPTED)
I have a search criteria depending on which i get the list as a result .
If the list contains only 1 data then i want to return to the edit view of that particular data.If list contains more than 1 data i want to return the jsonResponse to show the data table .
I tried with this but i did not get the data table nor did i get the view
if(reservationGridDataPage.getSize() > 1){
GridJSONResponse jsonResponse = ReservationGridHelper.prepareResponse(reservationGridDataPage);
jsonResponse.setiTotalDisplayRecords(gridManager.getTotalSearchedReservations(pageRequest, null, entityStateCode, searchParams));
jsonResponse.setsEcho(sEcho);
return jsonResponse;
}else{
Long entityKey = null;
List<ReservationGridData> content = reservationGridDataPage.getContent();
for (ReservationGridData t : content) {
entityKey = t.getId();
}
RedirectView redirectView = new RedirectView("/xxx/editRes?id="+entityKey);
return new ModelAndView(redirectView);
}
Just return the view name which is of typeString. Then, if reservationGridDataPage.getSize() > 1 returns true, redirect to another method of the controller anotated with #ResponseBody that will return your json object.
#RequestMapping(value = "//... your mapping blah blah ...", method = RequestMethod.POST)
public String method1(){
if(reservationGridDataPage.getSize() > 1){
return "redirect:/json-response.do";
}else{
Long entityKey = null;
List<ReservationGridData> content = reservationGridDataPage.getContent();
for (ReservationGridData t : content) {
entityKey = t.getId();
}
//...
//some other codes
return "the-name-of-my-edit-view";
}
}
#RequestMapping(value = "/json-response.do", method = RequestMethod.GET)
public #ResponseBody GridJSONResponse jsonResponseController(){
//... some other codes
GridJSONResponse jsonResponse = ReservationGridHelper.prepareResponse(reservationGridDataPage);
jsonResponse.setiTotalDisplayRecords(gridManager.getTotalSearchedReservations(pageRequest, null, entityStateCode, searchParams));
jsonResponse.setsEcho(sEcho);
//...
return GridJSONResponse;
}