How to unit test the catch exception statement? - java

How do I test the catch statement below? My coverlay is failing and I am not sure how to cover this line.
public Method execute(#NonNull final String test) throws ServiceException {
try {
object = javaClient.fetchInfo(test);
} catch (ClientException | InternalServerError e) {
throw serviceExceptionAdapter.apply(e);
}
return object;
}
This is currently what I have in my test file:
#BeforeEach
void setup() {
this.serviceExceptionAdapter = mock(ExceptionAdapter.class);
this.mockJavaClient = mock(JavaClient.class);
proxy = new Proxy(mockJavaClient, serviceExceptionAdapter);
}
#Test
void test_InternalServerError() {
when(mockJavaClient.fetchInfo(any())).thenThrow(InternalServerError.class);
when(serviceExceptionAdapter.apply(any())).thenThrow(ServiceException.class);
assertThrows(ServiceException.class, () -> proxy.execute(test));
verify(serviceExceptionAdapter, times(1)).apply(any());
}

I have to guess a little bit, as you didn't provide a full working example. From what I see in your catch block
} catch (ClientException | InternalServerError e) {
throw serviceExceptionAdapter.apply(e);
}
you expect the return value of your .apply(e) function to be an exception and throw that exception. In your test however, your mocked serviceExceptionAdapter doesn't return an Exception, but throws one instead:
when(serviceExceptionAdapter.apply(any()))
.thenThrow(ServiceException.class);
If my interpretations are correct, your code should work if you change the mentioned line in the test to the following:
when(serviceExceptionAdapter.apply(any()))
.thenReturn(new ServiceException(...));

Related

Why is mocking static method with Mockito not working in my case?

I have this complicated method. I want to mock just the result. All what is inside should basically be ignored. I am using Mockito .
class JiraManager
{
public static List<Issue> searchMitarbeiterIssue(String mitarbeiterName) throws JqlParseException, SearchException {
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class);
SearchService searchService = ComponentAccessor.getComponent(SearchService.class);
String jqlSearchString = "project = BLUB AND issuetype = BLOB AND text ~ \"" + myName+ "\""+" AND status = aktive";
final Query query = jqlQueryParser.parseQuery(jqlSearchString);
List<Issue> issues = null;
Query queryToExecute = JqlQueryBuilder.newBuilder(query).buildQuery();
// get results for the jql query
SearchResults searchResult = searchService.search(user, queryToExecute, PagerFilter.getUnlimitedFilter());
try {
Method newGetMethod = null;
try {
newGetMethod = SearchResults.class.getMethod("getIssues");
} catch (NoSuchMethodException e) {
try {
LOGGER.warn("SearchResults.getIssues does not exist - trying to use getResults!");
newGetMethod = SearchResults.class.getMethod("getResults");
} catch (NoSuchMethodError e2) {
LOGGER.error("SearchResults.getResults does not exist!");
}
}
if (newGetMethod != null) {
issues = (List<Issue>) newGetMethod.invoke(searchResult);
} else {
LOGGER.error("ERROR NO METHOD TO GET ISSUES !");
throw new RuntimeException("ICT: SearchResults Service from JIRA NOT AVAILABLE (getIssue / getResults)");
}
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
LOGGER.error("Jql Helper can not get search result (ICT)", e);
} catch (Exception e) {
LOGGER.error("Jql Helper can not get search result - other exception (ICT)", e);
}
return issues;
}
}
I do not want Mockito to run all the Code inside the method. It should just return the List . That's all . So I tried this:
try (MockedStatic<JiraManager> utilities = Mockito.mockStatic(JiraManager.class)) {
utilities.when(() -> JiraManager.searchMitarbeiterIssue(any()))
.thenReturn(Collections.singletonList(mitarbeiterIssueResult));
assertTrue(JiraManager.searchMitarbeiterIssue("").size() == 1);
}
But it is not working. It always returns null. Why ?? Is the code inside the method executed ? What is Mockito exactly doing ?
Below works for me.
Create MockedStatic class field
private MockedStatic<MyUtilClassWithStaticMethods> myUtil;
Initialise MockedStatic before each test case
#BeforeEach
void initialiseWorker() {
myUtil = mockStatic(MyUtilClassWithStaticMethods.class);
}
Close MockedStatic after each test case
#AfterEach
public void close() {
myUtil.close();
}
Mock static method behaviour in test case
#Test
void test() {
when(MyUtilClassWithStaticMethods.staticMethod(any())).thenReturn(null);
}
You can return list instead of null here.

JUnit test not catching exception

UPDATE: Here's the full test:
#Test(expected = NullPointerException.class)
public void testMissingData() throws Exception{
Resource<ObjectDataModel, Content, Status> resource = builder.build(content, argA1Response,
argA2Response, objFilterParam, argA3Response);}
And here's the build method:
public Resource<ObjectDataModel, Content, Status> build(Content argContent,
ResponseA1 argA1Response,
ResponseA2 argA2Response, String argObjectTypeFilter,
ResponseA3 argA3Response) {
try {
viewDataModel.setObjectType(this.buildObjectType(filteredObjectType,
argA1Response.getData().getDataObject().getCategories().get(0).getObjectTypes().get(0)));
}
catch (Exception e) {
String msg = "Exception occoured while buildng the Object Data Model";
LOG.error(msg, e);
}
// we have the required information gathered to return
return Resource.okFromDataAndContent(viewDataModel, argContent);
}
And here's the buildObjectType() method:
private ObjectType buildObjectType(ObjectTypes argA1ProductType,
PendingObjectTypes argA2ProductType) {
ProductType objectType = new ObjectType();
List<Plan> plans = argA1ObjectType.getPlan();
List<PendingObjectSummary> objPlans = argA1ObjectType.getData();
if (objectType.getData() == null) {
objectType.setData(new ArrayList<>());
}
PendingObjectSummary tempPlan = null;
for (Plan currPlan : plans) {
tempPlan = plans.stream()
.filter(plan -> plan.getObjId().equals(currPlan.getObjId()))
.findFirst()
.orElseThrow(NullPointerException::new);
}
return objectType;
}
I'm using an Optional to test for null and I can confirm that the exception is being thrown -- but JUnit isn't catching it. Here's the test case:
#Test(expected = NullPointerException.class)
public void testMissingData() throws Exception{
Object<> response = fixture.create();
assertNotNull(response);
assertNotNull(response.getData());
assertNull(resource.getData().getObjectType());
}
In my create method I'm simply iterating over a bunch of objects to try and find one that matches my ID; if not found then throw a NullPointerException:
for (Object currObj : objects) {
tempObj = myOtherCollection.stream()
.filter(obj -> obj.getId().equals(currObj.getId()))
.findFirst()
.orElseThrow(NullPointerException::new);
}
The JUnit output clearly isn't catching the exception - here's the output:
java.lang.AssertionError: Expected exception: java.lang.NullPointerException
And my tomcat logs are definitely throwing the exception here:
18:48:30.015 [main] ERROR com.myCompany.src.ModelBuilder - Exception occoured while buildng the Data Model
java.lang.NullPointerException: null
at java.util.Optional.orElseThrow(Optional.java:290)
The only issue I can see is that maybe where I assign tempObj that the code is wrong. Am I missing anything obvious? Thanks for any helpful tips.
You are catching the nullpointer exception so the exception is not propagated to your test.
see
try {
viewDataModel.setObjectType(this.buildObjectType(filteredObjectType,
argA1Response.getData().getDataObject().getCategories().get(0).getObjectTypes().get(0)));
}
catch (Exception e) {
String msg = "Exception occoured while buildng the Object Data Model";
LOG.error(msg, e);
}
If you want to test for an exception you could throw an exception in your error handling (for example a custom ObjectCreationExcepion) and assert that that one is thrown, like
try {
viewDataModel.setObjectType(this.buildObjectType(filteredObjectType,
argA1Response.getData().getDataObject().getCategories().get(0).getObjectTypes().get(0)));
}
catch (Exception e) {
String msg = "Exception occoured while buildng the Object Data Model";
LOG.error(msg, e);
throw new ObjectCreationException(msg);
}
and in your test
#Test(expected = ObjectCreationException.class)
public void testMissingData() throws Exception{
Object<> response = fixture.create();
}
#Test(expected = ObjectCreationException.class) only handles exceptions that are not handled within the tested code OR the test itself.
So what you could do is
public Resource<ObjectDataModel, Content, Status> build(Content argContent,
ResponseA1 argA1Response,
ResponseA2 argA2Response, String argObjectTypeFilter,
ResponseA3 argA3Response) throws NullPointerExceptions // << notice thrwoing declatration
{ // do some stuf}
and then in test you can handle it like you where trying by
public void testMissingData() throws Exception{
Resource<ObjectDataModel, Content, Status> resource = builder.build(content, argA1Response,
argA2Response, objFilterParam, argA3Response);
}

How to Junit test a try catch block in my code

I have a class with couple of methods and each with a try catch block to look for any exceptions.
The code as follows:
public ResponseEntity get() {
try {
.....
} catch (Exception e) {
output = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return output;
}
and I came up with a test case using Mokito to test the above scenario but confused how to enter into catch block of the above
#Test
public void testgetAllUsers_withoutexecp() {
when(sMock.getAll()).thenReturn(someList);
Assert.assertTrue(result.getStatusCode() == HttpStatus.OK );
}
#Test(expected=NullPointerException.class)
public void testgetAllUsers_execp() {
when(sMock.getAll()).thenReturn(null);
Assert.assertFalse(result.getStatusCode() == HttpStatus.OK );
}
I tried to raise a NullPointerException but still the catch block is left out in codecoverage (by which I assume it is not been tested). please help me to write a Junit test case for this to enter exception. I am very new to all these topics.
You can raise exception using thenThrow clause of Mockito:
when(serviceMock.getAllUser()).thenThrow(new NullPointerException("Error occurred"));
and then assert like this:
Assert.assertTrue(result.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR);
Expecting NullPointerException makes no sense. This will never happen, because you catch exceptions.
Instead, test for AppConstants.ERROR_MESSAGE9
and HttpStatus.INTERNAL_SERVER_ERROR

Catching Exception with JUnit #Test(expected=Exception.Class)

I am writing a test case using JUnit and I am trying to catch an Exception using #Test(expected=Exception.Class). For some reason I am unable to catch the exception. If I pass null it would throw NullPointerException and the test catches it because Exception is the parent class but on my Coverage report the exception is still not covered.
Method under test:
private static final String CONTENT_LENGTH = "Content-Length";
protected long getContentLength( MultivaluedMap<String, String> headers ) {
String length = headers.getFirst( CONTENT_LENGTH );
if( length != null ) {
try {
return Long.valueOf( length );
} catch( Exception e ) {}
}
return 0;
}
JUnit test case:
#Test(expected=Exception.class)
public void testGetContentLength() {
new TestBaseMessageBodyReader().getContentLength(null);
}
Any help would be appreciated.
Thanks
Catching generic exception is bad practice and even worse to catch an exception and do nothing. in your try catch you should catch NumberFormatException which is what Long.valueOf has the potential of throwing. Even then your jUnit will not never catch the exception because you are catching the exception but not doing anything with it, the method would always return 0 as it's currently written (provided you're not passing null)
Here is some code that would catch the exception on your unit test. I'd create two unit tests, one to catch your the first exception and one to catch the second.
protected long getContentLength(MultivaluedMap<String, String> headers)
{
if(null == headers)
{
throw new SomeCustomException("some message");
}
Long returnValue = 0;
String length = headers.getFirst(CONTENT_LENGTH);
try
{
returnValue = Long.valueOf(length);
}
catch (NumberFormatException e) {
// if you can recover handle it here
// if you can't recover then break the app
throw new SomeOtherCustomException("some other message");
}
return returnValue;
}

Why is the main method not covered?

main method:
public static void main(String[] args) throws Exception
{
if (args.length != EXPECTED_NUMBER_OF_ARGUMENTS)
{
System.err.println("Usage - java XFRCompiler ConfigXML PackageXML XFR");
}
String configXML = args[0];
String packageXML = args[1];
String xfr = args[2];
AutoConfigCompiler compiler = new AutoConfigCompiler();
compiler.setConfigDocument(loadDocument(configXML));
compiler.setPackageInfoDoc(loadDocument(packageXML));
// compiler.setVisiblityDoc(loadDocument("VisibilityFilter.xml"));
compiler.compileModel(xfr);
}
private static Document loadDocument(String fileName) throws Exception
{
TXDOMParser parser = (TXDOMParser) ParserFactory.makeParser(TXDOMParser.class.getName());
InputSource source = new InputSource(new FileInputStream(fileName));
parser.parse(source);
return parser.getDocument();
}
testcase:
#Test
public void testCompileModel() throws Exception
{
// construct parameters
URL configFile = Thread.currentThread().getContextClassLoader().getResource("Ford_2008_Mustang_Config.xml");
URL packageFile = Thread.currentThread().getContextClassLoader().getResource("Ford_2008_Mustang_Package.xml");
File tmpFile = new File("Ford_2008_Mustang_tmp.xfr");
if(!tmpFile.exists()) {
tmpFile.createNewFile();
}
String[] args = new String[]{configFile.getPath(),packageFile.getPath(),tmpFile.getPath()};
try {
// test main method
XFRCompiler.main(args);
} catch (Exception e) {
assertTrue(true);
}
try {
// test args length is less than 3
XFRCompiler.main(new String[]{"",""});
} catch (Exception e) {
//ignore
}
tmpFile.delete();
}
Coverage outputs displayed as the lines from String configXML = args[0]; in main method
are not covered.
assertTrue(true); is a pointless no-op
Remove the try/catch around the call to XFRCompiler.main(args);, since all it does is swallow excpetions and make debugging harder; most likely you will then see an exception that tells you where the problem is.
There should be a call to fail() after the call to XFRCompiler.main(new String[]{"",""}); since you expect it to throw an exception
Put the two calls in separate test methods.
I'm worried about all those assertTrue(true). If there can't be an exception, then the assert is not necessary. If there is an unexpected exception, then this code will swallow it and you will get the behavior you see right now.
Then, if you expect an exception, you should code like this:
try {
... code that will throw an exception ...
fail("No exception was thrown");
} catch (SpecficTypeOfException e) {
assertEquals("message", e.getMessage());
}
That way, wrong types of exception and the exception message will be checked.
PS: Don't post questions with "urgent". We already help as fast as we can.

Categories