How to test exception is thrown with Junit [duplicate] - java

This question already has answers here:
JUnit right way of test expected exceptions
(4 answers)
Closed 5 years ago.
I would like to know how I can write a unit test to get the catch block covered for the following method. The FOM.create(data) is a static method.
public String getValue(Data data) {
try {
return FOM.create(data);
} catch (UnsupportedEncodingException e) {
log.error("An error occured while creating data", e);
throw new IllegalStateException(e);
}
}
Currently this is my unit test but it doesn't hit the catch block:
#Test (expected = UnsupportedEncodingException.class)
public void shouldThrowUnsupportedEncodingException() {
doThrow(UnsupportedEncodingException.class).when(dataService).getUpdatedJWTToken(any(Data.class));
try {
dataService.getValue(data);
}catch (IllegalStateException e) {
verify(log).error(eq("An error occured while creating data"), any(UnsupportedEncodingException.class));
throw e;
}
}

You can check throwable exception if exception does not caught before unit test. In your case you cant check UnsupportedEncodingException but can check IllegalStateException.
Unit test must looks like:
#Test (expected = IllegalStateException.class)
public void shouldThrowIllegalStateException() {
dataService.getValue(data);
}
if you wanna to check UnsupportedEncodingException you must testing FOM.create(data) method

You can use JUnits exception rule like this:
public class SimpleExpectedExceptionTest {
#Rule
public ExpectedException thrown= ExpectedException.none();
#Test
public void throwsExceptionWithSpecificType() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("Substring in Exception message");
throw new NullPointerException();
}
}

Related

How to unit test the catch exception statement?

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(...));

Junit: expect / assertThrows doesn't work

How look my code, where exception was thrown:
(Lets say it is UserService.generate() )
try {
UrlDecoder.decode(someString); // invalid somestring here
...
} catch (UnsupportedEncodingException | RuntimeException e) {
customLogger("Exception message here");
}
How i am trying to catch this exception in test:
#Test(expected = IllegalArgumentExeception.class)
public void test() {
UserService u = new UserService();
u.generate("invalidString");
}
RESULT:
//info logs here
java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "^I"
//Exception details here
java.lang.AssertionError: Expected exception: java.lang.IllegalArgumentException
The javadoc for URLDecoder.decode(someString) states that it will not throw an exception. I believe you meant to use URLDecoder.decode(someString, StandardCharsets.UTF_8.name()). But the Unsupported encoding exception is only thrown if the Charset you ask for is not supported. Here's one way you can make the exception get thrown, along with a way to check that it was thrown. This answer uses Mockito, which is a very powerful mocking framework.
import org.mockito.Mockito;
public class UserService {
public void generate(String someString, String encoding) {
try {
URLDecoder.decode(someString, encoding);
} catch (UnsupportedEncodingException e) {
customLogger("Exception message here");
}
}
public void customLogger(String string) {
// Do something
}
}
#Test
public void testThrowsOnBadEncoding() {
UserService u = Mockito.spy(new UserService());
u.generate("vl%23%46", "unknown");
Mockito.verify(u).customLogger("Exception message here");
}

Java: Unreported exception Exception; must be caught or declared to be thrown [duplicate]

This question already has an answer here:
What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?
(1 answer)
Closed 7 months ago.
I get this error:
/student/src/reflection/tester/TestRunnerTests.java:21: error: unreported exception Exception; must be caught or declared to be thrown testRunner.runTests(testClassNames);
So it shows that the error must be on testRunner.runTests(testClassNames); line in this class:
public class TestRunnerTests {
#Test
public void runsTestsFromDecoupledFiles() throws Exception {
List<String> testClassNames = List.of(
"reflection.tester.ExampleTests1", "reflection.tester.ExampleTests2");
TestRunner testRunner = new TestRunner();
testRunner.runTests(testClassNames);
String result = testRunner.getResult();
assertThat(result, containsString("test1() - OK"));
assertThat(result, containsString("test2() - FAILED"));
assertThat(result, containsString("test3() - OK"));
assertThat(result, containsString("test4() - FAILED"));
assertThat(result, containsString("test5() - OK"));
assertThat(result, containsString("test6() - FAILED"));
assertThat(result, not(containsString("helperMethod()")));
}
}
My actual code looks like this:
public class TestRunner{
List<String> result = new LinkedList<>();
List<String> annotatedMethods = new LinkedList<>();
public void runTests(List<String> testClassNames) throws Exception {
for (String test: testClassNames) {
Class<?> aClass = Class.forName(test);
getClassMethods(aClass);
}
}
.....
}
Tried something like this, but it says A catch statement that catches an exception only to wrap it in a new instance of the same type of exception and throw it should be avoided
try{
for (String test: testClassNames) {
Class<?> aClass = Class.forName(test);
getClassMethods(aClass);
}
} catch (Exception e){
throw new Exception(e);
}
How should I solve it?
If you throw an Exeption you have to catch it anywhere. So you need to wrap the call of the method "runTests" into a try-catch
(General: You need to catch a thrown exception outside of this instance)
you wrote:
testRunner.runTests(testClassNames);
try:
try{testRunner.runTests(testClassNames);} catch (Exception e) {...}

finally block does not execute if exception is thrown [duplicate]

This question already has answers here:
Understanding checked vs unchecked exceptions in Java
(21 answers)
Closed 2 years ago.
finally block would execute if an exception is thrown in try block here:
public class ExceptionTest{
public static void main(String args[])
{
System.out.println(print());
}
public static int print()
{
try
{
throw new NullPointerException();
}
finally
{
System.out.println("Executing finally block");
}
}
}
output:
Executing finally block
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.print(ExceptionTest.java:11)
at ExceptionTest.main(ExceptionTest.java:4)
In the other hand finally won't be called in this code right here:
public class ExceptionTest{
public static void main(String args[])
{
System.out.println(print());
}
public static int print()
{
try
{
throw new Exception();
}
finally
{
System.out.println("Executing finally block");
}
}
}
output:
ExceptionTest.java:11: error: unreported exception Exception; must be caught or declared to be thrown
throw new Exception();
^
1 error
why it is cool with NullPointerException class but it complains when it comes to Exception class?
NullPointerException is an unchecked exception. Check this guide.
Here is an example of a try and catch block which catches everything:
try {
//Do Something
}
catch (Exception e) {
System.out.println("Something went wrong.");
}
finally {
System.out.println("The 'try catch' is finished.");
}

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);
}

Categories