How to unit test EventListenerProvider onEvent method of Keycloak - spring

EventListenerProvider.java class
#Override
public void onEvent(AdminEvent event, boolean includeRepresentation) {
log.info("Admin Event Occurred:" + toString(event));}`
Util.java class
public static String toString(AdminEvent adminEvent) {
StringBuilder sb = new StringBuilder();
sb.append("operationType=");
sb.append(adminEvent.getOperationType());
...
return sb.toString();
}
Test.java
#Test
void testOnEventAdminShouldLog() {
when(UtilClass.toString(adminEvent)).thenReturn("someString");
sessionEventProvider.onEvent(adminEvent, true);
verify(sessionEventProvider,times(1)).onEvent(adminEvent, true);
}
When I run the test it gives error as below:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object.
How to test this method ?
Thanks.

Related

Can this method be tested using mockito?

I am not sure how to test the first method in the service layer with Mockito as it is using the helper method. Below is my failed attempt at a test: I get an InvalidUseOfMatchersException in the second when clause.
Thanks in advance!
#Mock
private EntityRepository EntityRepo;
#InjectMocks
private EntityService EntityService;
public List<DTO> getAllDTOs(){
//first method
return entityRepo.findAll()
.stream()
.map(this::convertEntityToDTO)
.collect(Collectors.toList());
}
//helper method
public DTO convertEntityToDTO(Entity entity) {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.LOOSE);
DTO dto = new DTO();
dto = modelMapper.map(entity, DTO.class);
return dto;
}
#Test
public void EntityService_GetAll_ReturnsDTOList() {
when(entityRepo.findAll()).thenReturn(Mockito.anyList());
//the second when clause: when(entityService.convertEntityToDTO(Mockito.any(Entity.class)))
.thenReturn(Mockito.any(DTO.class));
List<DTO>DTOList = entityService.getAllDTOs();
Assertions.assertThat(DTOList).isNotNull();
Mockito#any* methods are actually defined in class ArgumentMatchers and can only be used to match the call arguments when setting up a mock or when verifying calls. All matcher methods return null (but have side-effects of modifying a matcher stack to be able to properly detect and match mocked calls).
For instance, you might do Mockito.when(svc.print(Mockito.anyString()).doNothing() when you don't care about the input or Mockito.verify(svc.print(Mockito.anyString()), Mockito.never()) when you want to verify that the method has never been called.
When setting up your mock, you have to provide a real value in your thenReturn call:
when(entityRepo.findAll()).thenReturn(Collections.emptyList());
when(entityService.convertEntityToDTO(Mockito.any(Entity.class)))
.thenReturn(new DTO());

PowerMock - Mock private method doesn´t work

I'm trying to mock a private method with PowerMock but the method I mock to always returns 0. I show you my classes to see if you can help me. Thank you.
Service.class
public int getNumber() { return getNumberPriv(); }
private int getNumberPriv() {
return 2;
}
ServiceTest.class
#SpringBootTest
#ActiveProfiles("test")
#RunWith(PowerMockRunner.class)
public class SharepointServiceTest {
#Test
public void fakeTest() throws Exception {
SharepointServiceImpl mock = PowerMockito.spy(new SharepointServiceImpl());
PowerMockito.doReturn(7).when(mock, "getNumberPriv");
int result = mock.getNumber(); //Always return 0
assertNotNull(result);
assertEquals(7, result);
}}
Probably something like you cannot mock calls to methods "within" the current class. There's no way to intercept the real call and hence no way to mock the response.

How to mock a particular method of a spring bean

I have a spring bean with multiple APIs. Mocking the bean doesn't serve my purpose as I would like to verify fetchFromDb() called only once on multiple calls to getCachedData() with the same input. This is to make sure the result is cached.
Is it possible to mock fetchFromDb() on bean 'market' while calling getCachedData()?
Sample Class
#Configuration("market")
public class AllMarket {
#Autowired
private CacheManager cachedData;
public boolean getCachedData(LocalDate giveDate) {
//check if it exists in cache
if(Objects.nonNull(checkCache(giveDate)) {
return checkCache(giveDate);
}
//fetch from database
boolean bool = fetchFromDb(givenDate);
cacheData(giveDate, bool);
return bool;
}
public boolean checkCache(LocalDate giveDate) {
return cacheManager.getData(givenDate);
}
public boolean fetchFromDb(LocalDate givenDate) {
//return the data from database
}
public void cacheData(LocalDate givenDate, boolean bool) {
cacheManager.addToCache(givenDate, bool);
}
}
You can use Mockito.spy() for this kind of test. In this case you should spy your AllMarket instance and stub fetchFromDb. At the end you can Mockito.verify that fetchFromDb was called exactly once. It will look something like this:
AllMarket spy = spy(allMarket);
when(spy.fetchFromDb(givenDate)).thenReturn(true); //you have boolean as a return type
...
verify(spy, times(1)).fetchFromDb(givenDate);
For more information, you can see Official Mockito doc
Maybe mockito argument captor could asist you. It lets you to capture method input and how many times method was called, also may other functions. Please check https://www.baeldung.com/mockito-annotations.

Jersey custom validators unittest

I have a REST service written with Jersey & Spring-Boot. I have written custom validator classes for POST params. I want to unittest the same. I could not figure out how to do it. My Validator looks like below:
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = ValidTaskForCreate.Validator.class)
public #interface ValidTaskForCreate {
String message() default "Invalid Request to create a Task";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
public class Validator implements ConstraintValidator<ValidTaskForCreate, Task> {
#Override
public void initialize(ValidTaskForCreate constraintAnnotation) {
}
#Override
public boolean isValid(final Task task, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
if(task.getName() == null || task.getName().isEmpty()) {
context.buildConstraintViolationWithTemplate("Task name should be specified").addConstraintViolation();
return false;
}
if(task.getTaskType() == null) {
context.buildConstraintViolationWithTemplate("Specify a valid TaskType in the range of [1..3]").addConstraintViolation();
return false;
}
return true;
}
}
}
Now i want to test the isValid() function by passing various Task objects. I am not sure how to call this method now.
I can create instance of Validator class like this,
ValidTaskForCreate.Validator taskValidator = null;
taskValidator = new ValidTaskForCreate.Validator();
To call isValid(), i can use taskValidator.isValid(). But i do not know how to create the ConstraintValidatorContext object to pass as 2nd parameter.
Or is there any way to UnitTest custom validations classes like this?
But i do not know how to create the ConstraintValidatorContext object to pass as 2nd parameter.
Just use Mockito and mock it. Then just verify that the correct methods were called. This is how to test the behavior of the unit when dependencies are involved.
private ConstraintValidatorContext context;
private ConstraintValidatorContext.ConstraintViolationBuilder builder;
#Before
public void setup() {
// mock the context
context = Mockito.mock(ConstraintValidatorContext.class);
// context.buildConstraintViolationWithTemplate returns
// ConstraintValidatorContext.ConstraintViolationBuilder
// so we mock that too as you will be calling one of it's methods
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
// when the context.buildConstraintViolationWithTemplate is called,
// the mock should return the builder.
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
.thenReturn(builder);
}
#Test
public void test() {
// call the unit to be tested
boolean result = ..isValid(badTask, context);
// assert the result
assertThat(result).isFalse();
// verify that the context is called with the correct argument
Mockito.verify(context)
.buildConstraintViolationWithTemplate("Task name should be specified");
}
Note the use of Mockito directly. In most cases you will probably just use static imports to make it less verbose. I just wanted to make it more readable
This is the best way I found using standard Spring unit testing with no need to mock anything.
#RunWith(SpringRunner.class)
#SpringBootTest(classes= {ValidationAutoConfiguration.class})
public class AllowedValuesValidatorTest {
#Autowired
private Validator validator;
#Test
public void testIsValid() {
ObjectToBeValidated obj = // create object
Set<ConstraintViolation<ObjectToBeValidated>> violations = validator.validate(obj);
boolean violationsFound =
violations.stream().anyMatch(v -> v.getConstraintDescriptor().getAnnotation().annotationType().equals(
NonNullLowercaseLettersOrNumbersOnly.class));
assertThat(externalIdViolationFound).isTrue();
}
}
It's the ValidationAutoConfiguration.class as the configuration of the test that does the heavy lifting. This will exercise all validation on the ObjectToBeValidated and you can search the violations for just that one you're testing for.

How to call private method by other methods?

I am confused of calling a private method by another method(public) belonging to the same class.Once I have been told I gotta create an object of that class and then call the private method via this object but in one of my questions in this forum I have been told that I dont need to use object.
public class Train() {
private void method1{......method definition..... }
public void method2{......how to invoke method1??}
}
Can I simply call the first method inside the second method by using method1(); or should I invoke it by creating an object of the class and Object_of_Train.method1();.
Which one should I use?
Within the class you should be able to call method1();
Outside the class you will need to call it from an instance of that class and will have access to public methods only
Use this.method1(); to call from method2() or any other non-static method in the class.
You can access the private methods of a class using java reflection package.
**Step1 − Instantiate the Method class of the java.lang.reflect package by passing the method name of the method which is declared private.
Step2 − Set the method accessible by passing value true to the setAccessible() method.
Step3 − Finally, invoke the method using the invoke() method.**
Example
import java.lang.reflect.Method;
public class DemoTest {
private void sampleMethod() {
System.out.println("hello");
}
}
public class SampleTest {
public static void main(String args[]) throws Exception {
Class c = Class.forName("DemoTest");
Object obj = c.newInstance();
Method method = c.getDeclaredMethod("sampleMethod", null);
method.setAccessible(true);
method.invoke(obj, null);
}
}
Source : Tutorialpoint

Resources