How do I mock local OAuth2RestTemplate restTemplate? - java

I have a method:
public void putObj(Doc doc) {
for (int i = 0; i < 3; i++) {
try {
OAuth2RestTemplate restTemplate = something.thatReturnsOAuth2RestTemplate(props);
restTemplate.postForEntity(somethingElse.getUrl(), doc.toJSONString(), String.class);
break;
} catch (HttpClientErrorException | HttpServerErrorException e) {
//do stuff in here
}
}
}
And my test class:
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest(OkHttp3TemplateUtil.class)
public class TestingClass {
#InjectMocks
private static MyService myService;
#Mock
private static Something something;
#Mock
private static Props props;
#Mock
private static OAuth2RestTemplate restTemplate;
#Test
public void testExceptionCaughtWhenThrownByRestTemplate(){
PowerMockito.mockStatic(OkHttp3TemplateUtil.class);
Doc doc = new Doc.docBuilder().setSomething("");
when(something.thatReturnsOAuth2RestTemplate(props)).thenReturn(restTemplate);
when(restTemplate.postForEntity("http://dummy.com", String.class, String.class)).thenThrow(HttpClientErrorException.class);
myService.putObj(doc);
}
}
No matter what I do, thenThrow never throws an exception. The test passes never providing coverage for code after catch. What am I missing here, I'm going mad!

It looks like you need to use matchers from Mockito.
In your case the 3 args for restTemplate are a bit confusing. The 1st is a String value so use anyString() to match it and mock out somethingElse.getUrl(), that code isn't in the example so not sure what it does but it must return a String and not be null. It looks like you want to match any string for the 2nd, with Mockito you need to use anyString() or any() if it is not a String to accomplish that. The 3rd is the actual value of String.class so again use eq(). Note, if any params are null it will not match. Also, it is easy to end up mocking out a different overloaded postForEntity if you're not careful.
For the something.thatReturnsOAuth2RestTemplate, you might be OK without a matcher. If the Props class has equals defined and both the test and production code values are equal. However, the example doesn't show this info, so I just added the any(Props.class) for that too.
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
#Test
public void testExceptionCaughtWhenThrownByRestTemplate(){
PowerMockito.mockStatic(OkHttp3TemplateUtil.class);
Doc doc = new Doc.docBuilder().setSomething("");
when(something.thatReturnsOAuth2RestTemplate(any(Props.class))).thenReturn(restTemplate);
when(restTemplate.postForEntity(anyString(), any(), eq(String.class))).thenReturn(response);
}

Related

How to mock a method which is type casted?

Class to be tested
public class KnockoutValidation {
public boolean runFormValidation(String param1, boolean param1, final String param3) {
//...
AccessBeanFactory fact = new AccessBeanFactory();
AccessBean bean = (AccessBean) fact.getAccessBean("abc", "xyz");
//....
}
}
Test Class
#RunWith(MockitoJUnitRunner.class)
public class KnockOutValidationTest {
#InjectMocks
KnockoutValidation KnockoutValidationMock;
#Mock
AccessBeanFactory factMock;
AccessBean accessBean;
#Before
public void setUp() {
accessBean = new AccessBean();
when(factMock.getAccessBean(anyString(), anyString())).thenReturn(accessBean);
}
#Test
public void doKnockoutValidationTest() {
Boolean result = KnockoutValidationMock.runFormValidation("a", true, "c");
Assert.assertEquals(result, true);
}
}
Even after mocking it is calling the actual implementation and throwing an exception and getting
java.lang.NullPointerException
ideally when we mock it should not execute actual method, here it is going into that getAccessBean method which is again a big API with a lot of try and catch blocks. So somewhere inside it is throwing an exception.
I just want to know why mocking is not working and how to mock this type of casted methods
I believe the way you had written implementation, it won't be possible reason is
AccessBeanFactory fact= new AccessBeanFactory();
instead you can
#Autowired private AccessBeanFactory fact;
Problem :- Every-time you call fact.getAccessBean with newly created object(instead of mock) while beans are not available. So it does throw NPE as expected
The #InjectMock won't work in this case because you are creating the AccessBeanFactory in place with a new constructor.
AccessBeanFactory fact= new AccessBeanFactory();;
You should have it as a field of the class, then the InjectMock will work, or better pass the factory as an argument.
Here is one example that should work. #InjectMock works by type, meaning that it will search through the class's field with Reflection and injects the mocks you specify with the #Mock annotation.
public class KnockoutValidation {
#Autowired
AccessBeanFactory fact;
public boolean runFormValidation(String param1, boolean param1, final String param3) {
//...
AccessBean bean = (AccessBean) fact.getAccessBean("abc", "xyz");
//....
}
}
You could also try to use PowerMockito's whenNew that will actually apply to the inline class creation, but that's a dark path you should avoid and only use with 3rd party codes.

JUnit test always returning null

I am writing a JUnit test case for my code, but the Mockito is always returning null
#Component
public class ConnectorImpl {
public String returnString(String inte) {
String x = testing();
return x;
}
public String testing() {
return "test";
}
}
Test class
#RunWith(MockitoJUnitRunner.class)
public class ConnectorImplTest {
#Mock public ConnectorImpl connector;
#Test
public void testLoggedInRefill() throws Exception {
Mockito.when(connector.testing()).thenReturn("test");
String x = connector.returnString("8807");
assertEquals("8807", x);
}
}
When I am calling connector.returnString("8807");, it is always returning null. Is there anything I am doing wrong? I am new to JUnit.
One way you can test your method returnString is as :
// mock 'returnString' method call
Mockito.when(connector.returnString(anyString()).thenReturn("test");
// assert that you've mocked succesfully
assertEquals("test", connector.returnString("8807"));
According to your code, you are mocking your ConnectorImpl
So it is an empty object and it means that it is up to you to specifically when(...).then(...) any functionality that you like to test.
BTW - if you are testing the ConnectorImpl then you should not mock it, but actually use the real bean. You should mock the beans that ConnectorImpl is using.
So I would suggest your code look maybe like that:
#RunWith(MockitoJUnitRunner.class)
public class ConnectorImplTest {
public ConnectorImpl connector = new ConnectorImpl(...);
#Test
public void testLoggedInRefill() throws Exception {
String x = connector.returnString("8807");
assertEquals("8807", x);
}
}
You are mocking the object and you do not specify any behaviour for the returnString method of the mocked object. As you did for testing(), you can do the same for returnString() method:
when(connector.returnString(anyString())).thenReturn("text")
On the other hand why do you need ti mock this class?

how to mock a method which returns future java object ,using mockito

I have a method validate for which i need to write junit test cases
public List<Field> validate(){
final Future<Map<ObjectId, Field>> uniqueResult = globalUniqValidator.execute(uniqueValidations,
validationContent.getEvalFieldValueMap(), inputFieldValuesMap);
final Future<Map<ObjectId, Field>> subnetResult = globalSubnetValidator.execute(subnetValidations,
validationContent.getEvalFieldValueMap(), inputFieldValuesMap, surveyTemplateRefId);
}
it has two methods which returns future object
#RunWith(MockitoJUnitRunner.class)
public class GlobalValidationServiceTest {
#Mock
private Future<Map<ObjectId, Field>> future;
#Test
public void validateGlobalValidation() throws Exception {
given(globalUniqValidator.execute(uniqueValidations, validationContent.getEvalFieldValueMap(), inputFieldValuesMap)).willReturn(future);
when(future.get()).thenReturn(inputFieldValuesMap);
given(globalSubnetValidator.execute(globalValidation, evalFieldValueMap, inputFieldValuesMap, surveyTemplateRefId)).willReturn(future);
when(future.get()).thenReturn(inputFieldValuesMap_subnet);
}
however when I debug I get a null for both uniqueResult and subnetResult
i guess it is not being mocked
it also says unused mock at the lines where the mock is written
Am I missing something ?

JUnit test cases using mockito for Rest API

I am new to Mockito framework , I have a rest APi that connects my application to jasper server and do report related operations.I want to write junit test cases for rest API using mockito framework.
here i have class called Repositoryclient , Its constructor have instance of JasperServerInfo DAO class.
public class RepositoryClient {
public RepositoryClient(ServerInfo serverInfo) {
this.info = serverInfo;
try {
Session = Client.authenticate(info.username.trim(), info.password.trim());
}
catch (Exception e) {
}
}
public void Templates() { //this method brings list of present report in jasper server repository
try {
OperationResult<...> result = ....;
} catch (Exception e) {
INodeProcessor.logger.warn(e.toString());
throw Error.REPORT_TEMPLATE_LIST_ERROR.with();
}
}
So how to write JUnit test cases using mockito for this class please guide me through. Thank you in advance.
Well, the code could be improved to make it actually testable...
At the moment, there is no really good way to write unit tests for your code, since the constructor creates a JasperserverRestClient without any chance to change it. The least you can do is add another constructor (may be package access) to allow another JasperserverRestClient to be used. (Alternatively you could think about using a Factory pattern. but this might be to complicated.)
Then you could mock that...
JasperserverRestClient jasperServerClient = Mockito.mock( JasperserverRestClient.class );
RestClientSession session = Mockito.mock( RestClientSession.class );
Mockito.when( jasperServerClient.authenticate( "x", "y")).thenReturn( session );
RepositoryClient repositoryClient = new RepositoryClient(jasperServerClient);
This would at least allow you to test, that authenticate is called with the correct parameters via Mockito.verify.
Also it would allow you to test that the listTemplates method calls the session with the correct parameters (of course you'll need to so some more mocking there).
An additional constructor, assuming your tests are in the same package, would look like this:
RepositoryClient(JasperserverRestClient httpRestClient, JasperServerInfo serverInfo) {
this.info = serverInfo;
this.httpRestClient = httpRestClient;
try {
restClientSession = httpRestClient.authenticate(info.username.trim(), info.password.trim());
}
catch (Exception e) {
INodeProcessor.logger.warn(e.toString());
throw Error.REPOSITORY_CLIENT_ERROR.with();
}
}
This way you can inject a mocked instance of your JasperserverRestClient into your object.
A test of your listTemplates method would (addtionally) look like this...
X resourcesService = Mockito.mock( X.class ); // No clue what the resourcesService() method is supposed to return, fill that in here
Mockito.when ( restClientSession.resourcesService() ).thenReturn ( resourcesService );
...This will allow the part restClientSession.resourcesService() to work. Next...
Y resources = Mockito.mock( Y.class ); // Same thing here, don't know what resources() should return, insert that class here
Mockito.when( resourcesService.resources()).thenReturn ( resources );
This will allow the resources() call to work.
Next we do some trickery:
Mockito.when( resources.parameter( Mockito.anyString(), Mockito.anyString()).thenReturn(resources); // assuming that ResourceSearchParameter constant is a String
This will allow the parameter() calls to work by returning the same resources() object.
And so on... You will need to when(...).thenReturn(...) the search method to return a OperationResult<ClientResourceListWrapper>, etc. but that's the same stuff as above.
And in the end, we could verify that the methods were called with the right parameters...
Mockito.verify( resources, Mockito.times(1)).parameter(ResourceSearchParameter.FOLDER_URI, info.reportDirectory);
Mockito.verify( resources, Mockito.times(1)).parameter(ResourceSearchParameter.RECURSIVE, "false"
Mockito.verify( resources, Mockito.times(1)).search();
getting started example that i have :
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#Test(priority = 31, groups = "success")
public void mockExample() {
Category category1 = mock(Category.class);
when(category1.getName()).thenReturn("Yess!!!");
System.out.println(category1.getName());
}
will print:"Yess!!!"
you can read from here :
http://examples.javacodegeeks.com/core-java/mockito/mockito-hello-world-example/
#RunWith(SpringJUnit4ClassRunner.class)
public class UserControllerTest {
#InjectMocks
private UserController userController;
#Mock
private RequestAttributes attrubutes;
#Mock
private UserService userService;
private MockMvc mockMvc;
#Before
public void setup() {
RequestContextHolder.setRequestAttributes(attrubutes);
this.mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
public void getUserinfoDetails() {
String userId = "123";
String userName = "Test145";
List<UserDto> userDtoList = new ArrayList<>();
Mockito.when(userService.getAllUserInfo()).thenReturn(userDtoList);
Assert.assertNotNull(userController.getUserinfo());
Assert.assertNotNull(userDtoList);
Assert.assertNotNull(userId);
Assert.assertNotNull(userName);
}
#Test
public void getUserByIdDetails() {
String userId = "123";
UserDto userDto = new UserDto();
Mockito.when(userService.getUserByUserId(userId)).thenReturn(userDto);
Assert.assertNotNull(userController.getUserById(userId));
Assert.assertNotNull(userDto);
Assert.assertNotNull(userId);
}
}
===========================================================================
for reference use below link:(step by step explanation)
https://www.youtube.com/watch?v=yGLOexeJfKA&t=17s

Mockito and string objects

I've started playing around with mockito today and I've encountered a problem. This is the class I'm trying to create test cases on:
#Path("search")
public class SearchWebService {
private static final Logger logger = Logger.getLogger(SearchWebService.class);
#EJB
UserServiceInterface userService;
#GET
#Path("/json/{searchstring}")
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
#RolesAllowed("User")
public List getJSONFromSearchResults(#PathParam("searchstring") String searchString, #Context HttpServletRequest request) {
logger.info("getJSONFromSearchResults called");
//Users own email
String ownemail = request.getRemoteUser();
if (searchString.contains(" ")) {
//Split String in two at first space
String names[] = searchString.split("\\s+", 2);
List userList = userService.searchByFullName(names[0], names[1], ownemail);
if (userList.size() > 0) {
return userList;
} //Check for cases where the last name contains spaces
else {
return userService.searchByLastName(searchString, ownemail);
}
}
return userService.searchBySingleName(searchString, ownemail);
}
}
I'm at searchString.contains(" ") and I'm trying to invoke "when(...).thenReturn(...)" But mockito throws an exception saying that "Cannot mock/spy class java.lang.String" I'm not sure I'm doing it correctly when testing this web service. Maybe there is some otherway to do this? Here is my test class:
public class SearchWebServiceTest {
#Mock
UserServiceInterface mockedUserService;
#Mock
Logger mockedLogger;
#Mock
HttpServletRequest mockedRequest;
#Mock
String mockedString;
#Mock
List<SearchResultsContainer> mockedUserList;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testGetJSONFromSearchResultsSpace() throws Exception {
when(mockedRequest.getRemoteUser()).thenReturn("email");
when("StringWithSpace".contains(" ")).thenReturn(true);
when("StringWitchSpace".split("\\s+", 2)).thenReturn(null);
when(mockedUserService.searchByFullName("name1", "name2", "email")).thenReturn(mockedUserList);
assertTrue(mockedUserList.size() > 0);
}
you cannot mock final classes (like String). This is a known limitation of the framework.
You can refer this link.
Mockito Verification Not Failing
I hope it helps !!!
If you need to invoke your service with a String that has a space, then just pass it a string that has a space. And don't mock the class that you are trying to test. You should mock as little as possible in unit tests. Simply provide real input data that meets the particular conditions of your particular test. Only mock collaborators, and only when you need to. If you need a String (either as a parameter or as a return value of a collaborator) that meets certain conditions, then just provide such an example String.
so if you need to test some method on string then best way is use reflection method to assign value to your string variable.
I used apache common library for it
FieldUtils.writeField(yourClass, "variableName", "value", true);

Categories

Resources