Test whether code throws a specific exception [duplicate] - java

This question already has answers here:
How do you assert that a certain exception is thrown in JUnit tests?
(35 answers)
JUnit 5: How to assert an exception is thrown?
(12 answers)
Closed 3 months ago.
I'm trying to test if an exception with a customized message is thrown when a division by zero is attempted.
Here's the method:
public static int getMultiplesOfGivenNumber(int number, int[] array){
int multiples = 0;
if (number == 0) {
throw new ArithmeticException("Number cannot be zero");
}else{
for (int i = 0; i < array.length; i++) {
if (array[i] % number == 0) {
multiples += 1;
}
}
}
After searching some solutions, I found this as a way to do the thing, but my IDE can't recognize 'expected' ...
#Test(expected=java.lang.ArithmeticException.class)
public void testDivideByZero(){
//arrange
int number = 0;
//act
int result = B3_E2.getMultiplesOfGivenNumber(number, intervalFromOneToTen());
//assert
assertEquals(expected, result);
}
I'm just unaware why my IDE is not recognizing 'expected'. Don't know if this has something to do with Junit version, or if there's some issue with the syntax I'm using.
In every other tests I used so far I never put nothing after #Test. I just found out this solution in another thread for a similar problem.

The expected argument to the #Test annotation exists only since JUnit 4. You must be using an earlier version of JUnit.
That having been said, you do not have to use this annotation, so you do not have to upgrade to JUnit 4 just for this feature.
You can use a try...catch yourself, and assert that the exception was thrown, and also assert that the custom message is what it is supposed to be.
#Test
public void testDivideByZero()
{
try
{
B3_E2.getMultiplesOfGivenNumber( 0, intervalFromOneToTen() );
assertTrue( false ); //expected exception was not thrown
}
catch( ArithmeticException e )
{
assertEquals( e.getMessage(), "Number cannot be zero" );
}
}
The benefit of going this way is that you can get your hands on the exception object, so you can examine its contents and make sure that it was initialized as expected. In the case of ArithmeticException there is nothing to check other than the message, but in other cases there may be a lot more to check.

Related

Trying to run junit test and get the following error: unreported exception Overflow; must be caught or declared to be thrown

I'm not supposed to touch the code, simply run junit tests on it.
I get the error whenever I run the insert method. I tested isFull (with assertFalse), so the exception shouldn't be thrown?
I get the error: unreported exception Overflow; must be caught or declared to be thrown
public void insert( int x ) throws Overflow
{
if( isFull( ) )
throw new Overflow( );
// Percolate up
int hole = ++currentSize;
for( ; hole > 1 && x< array[ hole / 2 ]; hole /= 2 )
array[ hole ] = array[ hole / 2 ];
array[ hole ] = x;
}
#Test
public void testBinaryHeapDefault() {
BinaryHeap bh1 = new BinaryHeap( 5 );
assertEquals(false, bh1.isFull( ));
bh1.insert( 2 );
}
As you say on comment in your question
I get the error: unreported exception Overflow; must be caught or declared to be thrown
The Java Language Spec requires that any Exception declared should be catch OR throw by a try-catch block OR declared in method name using the clause throws [Exception].
In your case, you can try one these:
Adding clause throws Overflow on the end of the method public void testBinaryHeapDefault()
Adding a try-catch block inside public void testBinaryHeapDefault()
Using the first approach,
#Test
public void testBinaryHeapDefault() throws Overflow{
BinaryHeap bh1 = new BinaryHeap( 5 );
assertEquals(false, bh1.isFull( ));
bh1.insert( 2 );
}
Notice that Overflow is not a Exception used by Java Core, so you need to put it inside your project. See some typical Exceptions List of Java Exceptions - JDK8

Can we replace "return" with "throw new Exception"? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to write a matrix calculator for decomposition. However, there are some cases in the matrix calculator where I don't want the system to return anything, but just print out an error message.
I have tried to do this by replacing the return call with a throw new Exception method, but it clearly doesn't seem to be working because: 1. there needs to be some sort of catch/throws implemented and 2. there is still a need for a return statement.
public double[][] multiply(Matrix other) {
if(getCols() == other.getRows()) {
double[][] mult = new double[getRows()][other.getCols()];
for(int r = 0; r < mult.length; r++) {
for(int c = 0; c < mult[0].length; c++) {
mult[r][c] = mult(m1[r],findCol(other,c));
}
}
return mult;
}
else {
throw new MatrixException("Multiply");
}
}
So as can be seen by the else statement, in place of a return statement, it is replaced with throw new MatrixException("Multiply"). This simply returns a String statement, but the code will not compile. Is there any way to use a try-catch method to throw the Exception without needing to implement a return? Also, yes this is the first time I'm asking a question, so I'm still not fully familiar with the question formatting techniques.
You could inform the caller of multiply that an exception can be thrown by changing your method like this:
public double[][] multiply(Matrix other)throws MatrixException{}
So the method now would be:
public double[][] multiply(Matrix other) throws MatrixException { // tells the method throws an exception
if(getCols() == other.getRows()) {
// ...
return <your_valid_return_here>
}
throw new MatrixException("Multiply"); // inform the caller there is an exception if the previous condition is not met
}
Also, bear in mind what type of exception is MatrixException (checked or unchecked) in order to follow this approach. If checked, the caller will be forced to handle it in the calling code (or report its code can throw the exception), not being like this if it is unchecked.
Additional reading:
When to choose checked and unchecked exceptions

Throw InterruptedException when using parallelStream - Java [duplicate]

This question already has answers here:
How can I throw CHECKED exceptions from inside Java 8 lambdas/streams?
(18 answers)
Closed 4 years ago.
I have a method with nested for loops as follows:
public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
MinSpecSetFamily result = new MinSpecSetFamily();
ResourceType minRT = this.getFirstEssentialResourceType();
if (minRT == null || minRT.noSpecies()) {
System.out.println("There is something wrong with the "
+ "minimal rticator, such as adjacent to no species. ");
}
for (Species spec : minRT.specList) {
ArrayList<SpecTreeNode> leafList = this.getMinimalConstSpecTreeRootedAt(spec).getLeaves();
for (SpecTreeNode leaf : leafList) {
result.addSpecSet(new SpecSet(leaf.getAncestors()));
}
}
return result;
}
This works fine, but the application is performance critical so I modified the method to use parallelStream() as follows:
public MinSpecSetFamily getMinDomSpecSets() throws InterruptedException {
ResourceType minRT = this.getFirstEssentialResourceType();
if (minRT == null || minRT.noSpecies()) {
System.out.println("There is something wrong with the "
+ "minimal rticator, such as adjacent to no species. ");
}
MinSpecSetFamily result = minRT.specList.parallelStream()
.flatMap(spec -> getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream())
.map(leaf -> new SpecSet(leaf.getAncestors()))
.collect(MinSpecSetFamily::new, MinSpecSetFamily::addSpecSet, MinSpecSetFamily::addMSSF);
return result;
}
This worked fine until I wanted to introduce an InterruptedException in the 'getLeaves()' method. Now the parallelStream version will not compile as it says I have an unreported InterruptedException which must be caught or declared to be thrown. I think this is because the parallelStream runs on multiple threads. No combination of try/catch blocks suggested by my IDE resolves the issue.
The second solution posted in Interrupt parallel Stream execution
suggests that I may be able to resolve the issue using ForkJoinPool but I have been unable to figure out how to modify my method to use this approach.
If you want to stick to your current design, you just need to catch the exception:
.flatMap(spec -> {
try {
return getMinimalConstSpecTreeRootedAt(spec).getLeaves().parallelStream();
} catch (InterruptedException e) {
// return something else to indicate interruption
// maybe an empty stream?
}
}).map(...)
Note that a parallel stream of parallel streams is possibly unnecessary and parallelising the top level stream only may be sufficient performance-wise.

To find line number where exception was thrown in java/grails

I have to write logic for detecting what line of code was exception thrown so we can go fix that issue later. The exception object's getStackTrace() gives us a list of stacktrace each with level. I am not interested in getting lowest place where exception was thrown but rather my class method which was responsible in passing parameters.
Here is an example of what i am asking
class Test {
void divide() {
try{
float i = 1/0
}
catch(Exception e){
def v = e.getStackTrace()[0]
println v.getClassName()
}
}
}
This would print class java.math.BigDecimal but i am interested in getting Test class so i can go to it's divide and fix this bug. Now, Test appears in some nth line which i cannot know in run time. One approach would be to iterate stacktrace list and try finding class which is custom developed but how to detect that? Or if there is some library function that already does that it would be great.
Try this:
println e.stackTrace.find {
it.className == 'Test' && it.methodName == 'divide'
}
Or, I guess you want to check all levels of stacktrace, then:
Throwable t = e
StackTraceElement found = null
while (!found && t) {
found = e.stackTrace.find {
it.className == 'Test' && it.methodName == 'divide'
}
t = e.cause
}
println found

error catching exception while System.out.print

I have 2 classes, one that implements a double lookup( int i);
and one where I use that lookup(int i) in solving a question, or in this case printing the lookup values. This case is for an array.
So I read the exception documentation or google/textbook and come with the following code:
public double lookup(int i) throws Exception
{
if( i > numItems)
throw new Exception("out of bounds");
return items[i];
}
and take it over to my class and try to print my set, where set is a name of the
object type I define in the class above.
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
System.out.print(set.lookup(i) + ",");
}
System.out.print(set.lookup(set.size()));
}
I'm using two print()'s to avoid the last "," in the print, but am getting an
unhandled exception Exception (my exception's name was Exception)
I think I have to catch my exception in my print() but cannot find the correct formatting online. Do I have to write
catch exception Exception? because that gives me a syntax error saying invalid type on catch.
Sources like
http://docs.oracle.com/javase/tutorial/essential/exceptions/
are of little help to me, I'm can't seem to grasp what the text is telling me. I'm also having trouble finding sources with multiple examples where I can actually understand the coding in the examples.
so could anybody give me a source/example for the above catch phrase and perhaps a decent source of examples for new Java programmers? my book is horrendous and I cannot seem to find an understandable example for the above catch phrase online.
I wouldn't throw Exception ever.
In your case, IndexOutOfBoundException or InvalidArgumentException would eb a better choice. As these are not checked Exceptions, you don't need to catch them.
public double lookup(int i) {
if(i >= numItems) // assuming numItems is not items.length
throw new IndexOutOfBoundException("out of bounds " + i + " >= " + numItems);
return items[i];
}
Note: the check should be >=
Your print() method will now compile unchanged.
What is Exception?
Exceptions are for exceptional conditions. Conditions that normally do not occur. Take an example you went to withdraw money and your account has 100 balance and you asked for 200 then ATM should tell you that you have insufficient balance.
Types of Exceptions
Checked Exception
These are conditions where application wants to recover from it. Like example given above application will give you error and will continue working.
Error
This is an exceptional condition which is external to application. We say OutOfMemoryError when there isn't enough memory available and application can not recover from it.
Runtime Exception /Unchecked Exception
These exceptions are applications exception but in this case application can not recover from it. E.g NullpointerException if value is null and you try do something nasty with it.
so of above three only checked exceptions need to be cached.
How to throw and Catch Checked Exception
Exception or any subclass of Exception is a checked exception. A checked exception can be thrown using throw clause. Once you throw an exception it becomes mandatory for you to include that in method declaration using throws clause.
So whoever want to use this method will now have to handle that exception. Handling exception means invoking alternative flows. Like in our case we displayed text to user "Error Invalid account number."
Calling function can also choose to propagate exceptions by adding throws clause for those exceptions which are thrown by method it is calling.
Generate:
public static double withdraw(int i) throws Exception {
if (i <= 0)// Out of bounds
throw new Exception("Invalid Account Number");
return 0.0;// something;
}
Handle:
try {
withdraw(0);
} catch (Exception e) {
// do something with exception here.
// Log the exception
System.out.println("Error Invalid account number.");
}
Propagate:
public static double callWithdraw(int i) throws Exception {//Propagate exceptions
return withdraw(i);
}
Try this
try
{
print(); //print() needs to throw the same exception
} catch(Exception e)
{
//handle exception
System.err.println(e.getMessage()+"\n\n"+e.printStackTrace());
}
//finally {
// cleanup here if you like
// }
or this
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
try
{
System.out.print(set.lookup(i) + ",");
} catch(Exception e)
{
//handle it here
}
}
System.out.print(set.lookup(set.size()));
}
Do note that using "throws" is kind of a easy way out; it's a cheap delegation that sometimes makes coding easier... if you can, you should try to always use try/catch instead of throws.
Just be aware that whenever you use something with "throws" eventually you will have to put that in a try/catch block and deal with it properly.
Generally to denote improper arguments passed into your method, use IllegalArgumentException which is a RuntimeException and should not be caught.
In this specific case you don't have to write any extra code, the ArrayIndexOutOfBoundsException should take care of improper array access.
Thrown to indicate that an array has been accessed with an illegal
index. The index is either negative or greater than or equal to the
size of the array.

Categories

Resources