Mocking a controller that do PUT function - java

I am trying to create a Mock of my controller to update data inside user. From the code I am trying to update only the email, password, and age. Is this how we should do the mock? Because I'm still really new with this Mockito and Junit
Controller Mock
#Test
public void testUpdateUserController() throws Exception{
String username = "User";
String email = "user#email.com";
String password = "password123";
int age = 90;
Mockito.when(userService.updateUser(username,email,password,age)).then(invocationOnMock -> {
User user = new User();
user.setUsername("User");
user.setEmail("user#user.com");
user.setPassword("123456");
user.setAge(12);
user.setAddress("11111");
user.setIsActive(true);
return Optional.of(user);
});
mockMvc.perform(MockMvcRequestBuilders.put(BASE_URL + "/users/{username}",username)
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(userService, Mockito.times(1)).updateUser(userCaptor.capture(),emailCaptor.capture(),passwordCaptor.capture(),ageCaptor.capture());
Assert.assertEquals("User", userCaptor.getValue());
Assert.assertEquals("user#email.com", emailCaptor.getValue());
Assert.assertEquals("password123", passwordCaptor.getValue());
Assert.assertEquals("90", ageCaptor.getValue());
Assert.assertEquals("11111", addressCaptor.getValue());
}
UserServiceImpl
#Override
public boolean updateUser(String username, String email, String password, Integer age) {
Optional<User> userList = userRepository.findByUsernameAndIsActiveTrue(username);
if (userList.isPresent()) {
User user = userList.get();
user.setEmail(email);
user.setPassword(password);
user.setAge(age);
userRepository.save(user);
return true;
} else {
return false;
}
}

Here is one of my code samples for MVC Mocks
#RunWith(PowerMockRunner.class)
public class TrainingControllerTest {
#Mock
private TrainingService trainingService;
#Mock
private FileStorageService fileStorageService;
#InjectMocks
private TrainingController controller = new TrainingController();
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(new ExceptionController())
.build();
}
#Test
public void testCreateHappyPath() throws Exception {
Training training = new Training();
Optional<Training> result = Optional.of(training);
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.createTraining(any(Training.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String trainingPayloadJSON = mapper.writerFor(Training.class).writeValueAsString(training);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.post(TestConstants.POST_TRAINING_URI)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(trainingPayloadJSON)
)
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
#Test
public void testPutHappyPath() throws Exception {
Training training = new Training();
Optional<Training> result = Optional.of(training);
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.update(any(Training.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String trainingPayloadJSON = mapper.writerFor(Training.class).writeValueAsString(training);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.put(TestConstants.GET_PUT_DELETE_TRAINING_URI, TestConstants.ID)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(trainingPayloadJSON)
)
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
#Test
public void testAddAttendeesHappyPath() throws Exception {
Attendees attendees = new Attendees();
Optional<Training> result = Optional.of(new Training());
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.registerTrainingAttendees(any(Attendees.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String attendeesPayloadJSON = mapper.writerFor(Attendees.class).writeValueAsString(attendees);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.post(TestConstants.ADD_ATTENDEES_URI)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(attendeesPayloadJSON)
)
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
}

Related

Catching an exception RESTEASY004645: templateValues entry was null

I am in the process of creating tests for AdminClientService, which whould create users into Keycloak database. In the main processing it works as it should, but while creating tests i bumped into this exception:
java.lang.NullPointerException: RESTEASY004645: templateValues entry was null
at com.springboot.services.KeycloakAdminClientServiceTest.createKeycloakUserTest(KeycloakAdminClientServiceTest.java:80)
Here is the test, I am currently running:
#SpringBootTest
public class KeycloakAdminClientServiceTest {
#Value("${keycloak.auth-server-url}")
public String serverUrl;
#Value("${keycloak.realm}")
public String realm;
#Value("${keycloak.resource}")
public String clientId;
#Value("${keycloak.credentials.secret}")
public String clientSecret;
// #Mock
// KeycloakProvider kcProvider = Mockito.mock(KeycloakProvider.class);
// #InjectMocks
//
// #BeforeEach
// void setMockOutput() {
// //when(helloService.get()).thenReturn("Hello Mockito");
// Mockito.when(kcProvider.getInstance()).thenReturn(KeycloakBuilder.builder()
// .realm(realm)
// .serverUrl(serverUrl)
// .clientId(clientId)
// .clientSecret(clientSecret)
// .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
// .build());
// }
KeycloakProvider kcProvider;
KeycloakAdminClientService kcAdminClientService;
#BeforeEach
void createKeycloakProvider() {
kcProvider = new KeycloakProvider();
kcProvider.setServerUrl(serverUrl);
kcProvider.setRealm(realm);
kcProvider.setClientId(clientId);
kcProvider.setClientSecret(clientSecret);
kcAdminClientService = new KeycloakAdminClientService(kcProvider);
}
#Test
public void createKeycloakUserTest(){
Integer generatedInteger = (int) ((Math.random() * (9999999 - 1000000)) + 1000000);
String generatedString = generatedInteger.toString();
CreateUserRequest createUserRequest = new CreateUserRequest();
createUserRequest.setUsername("admin_client_username_" + generatedString);
createUserRequest.setPassword("admin_client_password");
createUserRequest.setEmail("admin_client_email_" + generatedString + "#gmail.com");
createUserRequest.setFirstname("admin_client_firstname_" + generatedString);
createUserRequest.setLastname("admin_client_lastname_" + generatedString);
kcAdminClientService.createKeycloakUser(createUserRequest);
UsersResource usersResource = kcProvider.getInstance()
.realm(kcAdminClientService.realm).users();
List<UserRepresentation> userRepresentation = usersResource
.search("admin_client_email_" + generatedString + "#gmail.com");
assertNotNull(userRepresentation);
assertEquals("admin_client_firstname_" + generatedString,
userRepresentation.get(0).getFirstName());
}
}
Here is the service:
#Service
public class KeycloakAdminClientService {
#Value("${keycloak.realm}")
public String realm;
private final KeycloakProvider kcProvider;
public KeycloakAdminClientService(KeycloakProvider keycloakProvider) {
this.kcProvider = keycloakProvider;
}
public Response createKeycloakUser(CreateUserRequest user) {
UsersResource usersResource = kcProvider.getInstance().realm(realm).users();
CredentialRepresentation credentialRepresentation = createPasswordCredentials(
user.getPassword());
UserRepresentation kcUser = new UserRepresentation();
kcUser.setUsername(user.getEmail());
kcUser.setCredentials(Collections.singletonList(credentialRepresentation));
kcUser.setFirstName(user.getFirstname());
kcUser.setLastName(user.getLastname());
kcUser.setEmail(user.getEmail());
kcUser.setEnabled(true);
kcUser.setEmailVerified(false);
Response response = usersResource.create(kcUser);
return response;
}
private static CredentialRepresentation createPasswordCredentials(String password) {
CredentialRepresentation passwordCredentials = new CredentialRepresentation();
passwordCredentials.setTemporary(false);
passwordCredentials.setType(CredentialRepresentation.PASSWORD);
passwordCredentials.setValue(password);
return passwordCredentials;
}
}
and the KeycloakProvider:
#Configuration
#Getter
#Setter
public class KeycloakProvider {
#Value("${keycloak.auth-server-url}")
public String serverUrl;
#Value("${keycloak.realm}")
public String realm;
#Value("${keycloak.resource}")
public String clientId;
#Value("${keycloak.credentials.secret}")
public String clientSecret;
private static Keycloak keycloak = null;
public KeycloakProvider() {
}
public Keycloak getInstance() {
if (keycloak == null) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.build();
}
return keycloak;
}
public KeycloakBuilder newKeycloakBuilderWithPasswordCredentials(
String username,
String password) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.username(username)
.password(password);
}
public JsonNode refreshToken(String refreshToken) throws UnirestException {
String url = serverUrl + "/realms/" + realm + "/protocol/openid-connect/token";
return Unirest.post(url)
.header("Content-Type", "application/x-www-form-urlencoded")
.field("client_id", clientId)
.field("client_secret", clientSecret)
.field("refresh_token", refreshToken)
.field("grant_type", "refresh_token")
.asJson().getBody();
}
}
I tried using Mockito for this problem, but realized it won't work, as I wanted it to.
Solved it myself, instead of that code above you just should write it like that, should've wrote #Autowired.
#Autowired
KeycloakProvider kcProvider;
#Autowired
KeycloakAdminClientService kcAdminClientService;
and it would solve all the problems)

How can add Bearer before token

PostMan
My BaseController code
#SuppressWarnings("unused")
#Autowired
private UserService userService;
public User handleTokenAccess(String encodeString) throws Exception {
byte[] decodedBytes = Base64.getMimeDecoder().decode(encodeString);
String decodedMime = new String(decodedBytes);
ObjectMapper mapper = new ObjectMapper();
try {
UserClient map = mapper.readValue(decodedMime, UserClient.class);
User user = userService.findOne(map.getUserId());
if (user != null)
return user;
else
throw new Exception();
} catch (Exception e) {
throw new Exception("Sai token , vui lòng chim cút");
}
}
My CategoriesController code
#RestController
#RequestMapping("/api/categories")
public class CategoriesController extends BaseController {
#Autowired
private CategoriesService categoriesService;
#Autowired
UserService userService;
#RequestMapping(value = "/create-category", method = RequestMethod.POST, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<BaseResponse> create(#Valid #RequestBody CRUDCategories wrapper,
#RequestHeader(value = "Authorization") String token) throws Exception {
BaseResponse response = new BaseResponse();
User userToken = this.handleTokenAccess(token);
Categories category = categoriesService.spUCreateCategory(userToken.getId(), wrapper.get_name(),
wrapper.getDescpiption(), wrapper.get_sort());
response.setData(new CategoriesResponse(category));
return new ResponseEntity<BaseResponse>(response, HttpStatus.OK);
}
}

How to pass client Id and client secret to a method while calling Junit

I am trying to write a test case for a method which calls a service with client Id and client Secret.But i am getting nullpointer exception from the Junit.I am not able to pass the clientId and client secret using Junit below is my code
#Service
public class ourClientServiceImpl implements ourClientService {
private static final Logger ourClientServiceLogger = LoggerFactory.getLogger(ourClientServiceImpl.class);
#Value("${service-description.our-service.base-url}")
private String ourServiceBaseUrl;
#Value("${service-description.posting-service.subscription-key}")
private String subscriptionKey;
#Autowired
#Qualifier("clientRestTemplate")
private RestTemplate clientRestTemplate;
#Value("${token.scope}")
private String scope;
#Value("${token.grantType}")
private String grantType;
#Autowired
private PingfedConfig config;
/**
* Method to fetch our Name based on our Number
*
* #param ourNumber ourNumber
* #return our Details
*/
#Override
public ourResponse fetchDetailsClient(String ourNumber) {
ourClientServiceLogger.info("Fetching our name for our number::{}", ourNumber);
final String resourceUrl = ourServiceBaseUrl + "/our?our-number=" + ourNumber;
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(resourceUrl);
UriComponents uriComponents = builder.build().encode();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + getJWTAuthenticationToken());
ResponseEntity<ourResponse> ourServiceResponseResponse = clientRestTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, new HttpEntity<>("parameters", headers),
new ParameterizedTypeReference<ourResponse>() {
});
return ourServiceResponseResponse.getBody();
}
private String getJWTAuthenticationToken() {
ourClientServiceLogger.info("Getting the JWT token");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBasicAuth(config.getClientId(), config.getClientSecret());
HttpEntity formEntity = new HttpEntity<>(null, headers);
ResponseEntity<JWTTokenResponse> jwtToken = clientRestTemplate.exchange(config.getTokenUrl() + "?grant_type=client_credentials&Scope=openid", HttpMethod.POST, formEntity, JWTTokenResponse.class);
if (jwtToken != null && jwtToken.getBody() != null) {
return jwtToken.getBody().getAccessToken();
} else {
return null;
}
}
}
The jUnit class
#RunWith(MockitoJUnitRunner.class)
public class OurClientServiceTest {
private final OurResponse expectedOurResponse = OurResponse.builder().eourNumber("15253").ourName("New").build();
private static final String jwtMockToken = "Bearer vgftyuuuuuuuuuuuuuuuuuuuu";
private final JWTTokenResponse jwtTokenResponse = JWTTokenResponse.builder().tokenType("Bearer").expiresIn("Now").extExpiresIn("Now").expiresOn("Now").notBefore("Now").resource("Now").accessToken(jwtMockToken).build();
#InjectMocks
private OurClientServiceImpl ourClientService;
#Mock
#Qualifier("clientRestTemplate")
private RestTemplate clientRestTemplate;
#Autowired
private PingfedConfig config;
OurResponse ourResponse = OurResponse.builder().ourNumber("15253").build();
ResponseEntity<OurResponse> ourResponseEntity = new ResponseEntity<>(ourResponse, HttpStatus.OK);
ResponseEntity<JWTTokenResponse> jwtTokenResponseEntity = new ResponseEntity<>(jwtTokenResponse, HttpStatus.OK);
#Before
public void setJwtTokenResponseEntity() {
when(clientRestTemplate.exchange(
anyString(),
any(HttpMethod.class),
any(HttpEntity.class),
eq(JWTTokenResponse.class))).thenReturn(jwtTokenResponseEntity);
}
#Test
public void testFetchOurDetailsClient() {
when(clientRestTemplate.exchange(
anyString(),
any(HttpMethod.class),
any(HttpEntity.class),
eq(VendorResponse.class))).thenReturn(ourResponseEntity);
OurResponse actualResponse = ourClientService.fetchVendorDetailsClient("15253");
Assert.assertEquals(expectedOurResponse.getVendorNumber(), actualOurResponse.getOurNumber());
Assert.assertEquals(expectedOurResponse.getVendorName(), actualOurResponse.getOurName());
}
}
Please let me know where i am doing wrong .Thanks in advance

ControllerAdvice didn't catch an BindingResult errors

I'm trying to override default error messages in BindingResult. I implemented Controller advice like this
#ControllerAdvice
public final class DefaultControllerAdvice {
private static final String ERROR_MESSAGE_FORMATTER = " - ";
#ExceptionHandler(BindException.class)
#ResponseStatus(value = HttpStatus.BAD_REQUEST)
public List<String> handleValidationException(final BindException exception) {
return exception.getBindingResult()
.getAllErrors()
.stream()
.filter(error -> error instanceof FieldError)
.map(objectError -> (FieldError) objectError)
.map(errorMessageFormatter)
.collect(Collectors.toList());
}
private final Function<FieldError, String> errorMessageFormatter =
error -> error.getField() + ERROR_MESSAGE_FORMATTER + error.getDefaultMessage();
}
and my controller
#PostMapping(value = "/register")
private String postRegistration( #ModelAttribute #Valid final UserCreateFormDto user, final BindingResult result,
final RedirectAttributes redirectAttributes, final WebRequest webRequest) {
try {
if (result.hasErrors()) {
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.user", result);
redirectAttributes.addFlashAttribute("user", user);
throw new BindException(result);
}
if (userService.checkEmailExist(user.getEmail())) {
throw new UserNotExistsException("User with email: "+ user.getEmail()+" already exists.");
}
final User registered = userService.createNewUserAccount(user);
final String appUrl = webRequest.getContextPath();
eventPublisher.publishEvent(
new RegistrationCompleteEvent(registered, webRequest.getLocale(), appUrl));
return "redirect:/login?success";
} catch (UserNotExistsException error) {
return "redirect:/register?exists";
} catch (BindException error) {
return "redirect:/register";
}
}
and test case
#Test
public void shouldNotCreateUserWhenUsernameIsEmpty() throws Exception {
//given
final UserCreateFormDto userCreateFormDto = createUserCreateForm();
final User user = createUser();
given(userService.checkEmailExist(userCreateFormDto.getEmail())).willReturn(false);
given(userService.createNewUserAccount(any(UserCreateFormDto.class))).willReturn(user);
//when
final MvcResult response = mockMvc
.perform(post("/register").with(csrf())
.contentType(MediaType.MULTIPART_FORM_DATA)
.param("username","")
.param("email",userCreateFormDto.getEmail())
.param("password", Arrays.toString(userCreateFormDto.getPassword()))
.param("matchingPassword", Arrays.toString(userCreateFormDto.getMatchingPassword())))
.andReturn();
//then
assertThat(response.getFlashMap().isEmpty()).isFalse();
assertThat(response.getResponse().getStatus()).isEqualTo(HttpStatus.FOUND.value());
assertThat(response.getResponse().getRedirectedUrl()).isEqualTo("/register");
verify(userService, times(1)).checkEmailExist(userCreateFormDto.getEmail());
verify(userService, times(0)).createNewUserAccount(any(UserCreateFormDto.class));
my question is how to get the bindingResult default error message?
I would like to test what an error message is getting while validate input fields.

How to test Rest API and mock url using spring boot and mockbeam

I have a Rest API
The class code is :
#SpringBootTest
#RunWith(SpringRunner.class)
public class FetchCoreVersionsListIT {
#MockBean
private RestTemplateBuilder restTemplateBuilder;
#MockBean
private RestTemplate restTemplate;
private VersionsService versionsService;
#Autowired
private FetchCoreVersionsList fetchCoreVersionsList;
private VersionList versionList;
private ArtifactoryFolderInfoChild version;
#Before
public void setUp() throws Exception {
this.version = new ArtifactoryFolderInfoChild();
this.version.setUri("2.1.0");
this.version.setFolder(true);
when(restTemplateBuilder.build()).thenReturn(restTemplate);
}
#Test
public void testCoreVersionsJsonHandle() throws Exception{
when(restTemplate.getForObject("https://openmrs.jfrog.io/openmrs/api/storage/public/org/openmrs/api/openmrs-api/",
String.class))
.thenReturn(getFileAsString("core-versions.json"));
("2.1.0"));*/
}
This is the core-versions.json . This is nothing else but the data received from this Rest API.
Basically I'm trying to run a test and I have a spring schedule that will parse the json received from that Rest url. Now, while testing the schedule, I want to return the same data but without connecting to the internet and hence want to return the contents of core-versions.json. I get the following error unfortunately :
java.lang.IllegalStateException: File downloaded from could not be parsed
My schedule class is this:
#Component
public class FetchCoreVersionsList {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String[] STRINGS_TO_EXCLUDE = {"alpha", "beta", "RC", "SNAPSHOT"};
#Value("${core_version_list.url}")
private String url;
//#Value("${core_version_list.strategy}")
//private FetchCoreVersionsList.Strategy strategy = FetchCoreVersionsList.Strategy.FETCH;
private RestTemplateBuilder restTemplateBuilder;
private ObjectMapper mapper;
private VersionsService versionsService;
#Autowired
public FetchCoreVersionsList(RestTemplateBuilder restTemplateBuilder,
ObjectMapper mapper,
VersionsService versionsService) {
this.restTemplateBuilder = restTemplateBuilder;
this.mapper = mapper;
this.versionsService = versionsService;
}
#Scheduled(
initialDelayString = "${scheduler.fetch_core_versions_list.initial_delay}",
fixedDelayString = "${scheduler.fetch_core_versions_list.period}")
public void fetchCoreVersionsList() throws Exception {
logger.info("Fetching list of OpenMRS-Core versions");
// FetchCoreVersionsList.Strategy strategy = FetchCoreVersionsList.Strategy.FETCH;
String json;
/* if (strategy == Strategy.LOCAL) {
logger.debug("LOCAL strategy");
json = StreamUtils.copyToString(getClass().getClassLoader().getResourceAsStream("openmrs-core-versions.json"),
Charset.defaultCharset());
} else {*/
json = restTemplateBuilder.build().getForObject(url, String.class);
logger.info("FETCH strategy: " + json);
ArtifactoryFolderInfo versionlist;
try { logger.info("FETCH strategy: " + json);
logger.debug("papa strategy: " + url);
versionlist = mapper.readValue(json, ArtifactoryFolderInfo.class);
} catch (Exception ex) {
throw new IllegalStateException("File downloaded from " + url + " could not be parsed", ex);
}
if (logger.isInfoEnabled()) {
logger.info("There are " + versionlist.getChildren().size() + " openmrs-core versions");
}
if (versionlist.size() > 0) {
List<String> versions = new ArrayList<>();
List<ArtifactoryFolderInfoChild> allversions = versionlist.getChildren();
for (ArtifactoryFolderInfoChild candidateVersion : allversions) {
if (candidateVersion.getFolder() && !stringContainsItemFromList(candidateVersion.getUri(), STRINGS_TO_EXCLUDE)) {
versions.add(candidateVersion.getUri().replaceAll("/", ""));
}
}
versionsService.setVersions(versions);
} else {
logger.warn("File downloaded from " + url + " does not list any Core Versions to index. Keeping our current list");
}
}
private static boolean stringContainsItemFromList(String inputStr, String[] items) {
return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}
public enum Strategy {
FETCH, LOCAL
}
}
Kindly bear with me if this is a silly error as I am completely new to testing.

Categories

Resources