Explain what this fail() method does in this junit test - java

I am having a bit of trouble understanding with the fail() method for JUnit tests does in practice. I looked around online and saw from the junit website that fail(java.lang.String message) "Fails a test with the given message." In the JUnit test I'm looking at, this is the following code:
#Test (expected = RuntimeException.class)
public void testBadCombine(){
AvocadoPortion ap1 = new AvocadoPortion(amount1);
AvocadoPortion ap2 = new AvocadoPortion(amount2);
IngredientPortion ap3 = ap1.combine(ap2);
CrabPortion cp1= new CrabPortion(2);
ap1.combine(cp1);
fail("Expected RuntimeException to be thrown");
}
Can someone please explain what the (expected = RuntimeException.class) does?
And if a RuntimeException IS thrown, does the fail("Expected RuntimeException to be thrown"); line not get executed, making the JUnit test succeed?
Why is the ap.1combine(cp1); line not under a try and catch block? (When do you need to use a try and catch block?)
As you can see I'm pretty confused and could use some clarification

The reasonable options to make that testing code more clear:
A) just use expected
#Test (expected = RuntimeException.class)
public void testBadCombine(){
AvocadoPortion ap1 = new AvocadoPortion(amount1);
AvocadoPortion ap2 = new AvocadoPortion(amount2);
IngredientPortion ap3 = ap1.combine(ap2);
CrabPortion cp1= new CrabPortion(2);
ap1.combine(cp1);
}
B) If required, do some specific testing on your exception ...
#Test
public void testBadCombine(){
AvocadoPortion ap1 = new AvocadoPortion(amount1);
AvocadoPortion ap2 = new AvocadoPortion(amount2);
IngredientPortion ap3 = ap1.combine(ap2);
CrabPortion cp1= new CrabPortion(2);
try {
ap1.combine(cp1);
fail("should have thrown");
} catch (TheExactExceptionYouExpect e) {
assertThat(e.getSomeProperty(), is(whatever));
}
}
You would prefer option "A)" - you only turn to "B") when in fact you want to assert certain properties of that exception thrown by the code under test.

Can someone please explain what the (expected = RuntimeException.class) does?
It requires the test to throw a RuntimeException in order to pass.
And if a RuntimeException IS thrown, does the fail("Expected RuntimeException to be thrown"); line not get executed, making the JUnit test succeed?
Exactly. This is technically redundant because of the expected element above. The only difference is that any Throwable would pass this check, but not the previous one.
Why is the ap.1combine(cp1); line not under a try and catch block? (When do you need to use a try and catch block?)
Try/catch is normally used for gracefully handling an exceptional situation. In other words, if an issue comes up, we want to solve it or work around it and then proceed normally. Here, we take the opposite approach and propagate the exception instead of handling it, so JUnit can know the exception was thrown.

You are correct, it is redundant to have both the expected and the fail(). One of them would be enough and hence appropriate.
For most exception types, you are also correct that if you want to use fail() rather than expected, you would use a try-catch statement with fail() in the end of the try part. In this respect, RuntimeException is special since it is the parent exception of all unchecked exceptions. Since no statement in the method can throw any checked exceptions, we know that either an unchecked exception is thrown, that is, a RuntimeException, or the method will reach the call to fail(). One or the other, not both.

Related

Java: How to propagate a "method exit" when tucking-in exceptions?

By "method exit" - I mean the actions in a method such as return or throw new... that the compiler considers the end of a method - if you could please tell me the accepted word for "method exit", I will edit the question
My problem is the following:
I do a lot of throw new RuntimeException(...
So, I decided to "tuck it in" as:
public static void quickRaise (String msg) { throw new RuntimeException(msg); }
And then I can reuse it.
(This will help me in the future to enhance the procedure around raising Runtime Exceptions and even
switch to a custom Exception class, without fishing in the code for exception throws)
However, where before I could write:
public MyType doSomething() {
try {
//...
return new MyType (parameter);
} catch (Exception e) {
throw new RuntimeException("msg")
}
}
And the compiler would correctly understand that "this method either exits by return or by throw" and therefore there are no logical "dead ends"
When I changed throw new RuntimeException("msg") to quickRaise("msg"), the compiler no longer considers my method "complete". It complains about a missing return statement, even though quickRaise is semantically equivalent to throw (or at least this is what I am trying to do!)
Let me try to reiterate the problem by a reproductive example (this will not compile, which is the problem):
public static void main(String[] args) {
System.out.println(doSomething());
}
public static String doSomething () {
try {
//... Some fun stuff going on here
return "Something";
} catch (Exception e) {
quickRaise("Could not find handshakes");
//throw new RuntimeException("If you uncomment this line, it will compile!");
}
}
public static void quickRaise (String msg) {
throw new RuntimeException(msg);
}
Your idea is highly inadvisable.
For example, this is just bad codestyle:
try {
someIO();
} catch (IOException e) {
throw new RuntimeException("Problem with IO");
}
The reason it's bad is that you have now obliterated the actual information about the problem. That information is locked into 5 separate parts of that exception you just caught: Its type (for example, FileNotFoundException, its message (e.g. "Directory /foo/bar does not exist"), its stack trace, its causal chain, and as throwables are objects, any particular extra detail for that particular kind of exception (such as the DB-engine-specific error coding for some SQLException).
Throwing this info away is silly.
All you'd need to do to fix this, is to add the cause:
} catch (IOException e) {
throw new RuntimeException("IO problem", e);
}
Now the IOException is marked as the cause of the exception you are throwing, which means in error logs you'll see it + the message + the stack trace of it + the stack trace of any causes it had as well.
All you need to do to make the compiler realize that the method ends here, is to throw it:
public static RuntimeException quickRaise(String msg) {
throw new RuntimeException(msg);
return null; // doesn't matter, we never get here
}
// to use:
throw quickRaise(msg);
But, as I explained before, this is a very bad idea.
Secondarily, having the idea of 'I just want to throw an exception and maybe later I want to replace the kind of exception I throw' also doesn't really work out: You need to pick a proper exception for the situation, therefore you cannot write a one-size-fits-all throw method in the first place.
Okay, so what do I do?
Primarily, learn to embrace throws clauses. If your method fundamentally does I/O (for example, the javadoc of it and/or the name makes that obvious, it is for example saveGame(Path p), or scanUserHome), then it should be declared to throws IOException.
If your method is an entrypoint (as in, it is the first point where your own code begins running), then your method should be declared to throws Exception. For example, your public static void main() method should throws Exception. Sometimes an entrypoint isn't main but something else (a webhandler routing hook for example), and sometimes backwards silly franeworks prevent you from doing that, but there tends to be a wrap functionality (such as } catch (Exception e) { throw new ServletException(e); }).
For exceptions which are both [A] fundamentally not part of the method's purpose, but more part of an implementation detail and [B] is very unlikely to go wrong and there's not much you can do other than hard crash if it would, then, yeah, rewrap as RuntimeException. There isn't a lot of point in ever changing this 'globally' for all such exceptions. At best you belatedly realize that failure is a bit more likely than you originally thought and either create a proper exception for it and document this behaviour. But that's, again, on a per-method basis, not something you can apply in blanket fashion.
Your approach is fundamentally at odds with the need for the compiler to see that the flow terminates at the throw statement.
I'd suggest having a utility method that just constructs an exception, which you then throw from the original point.
It's either than or put dummy returns after each call to quickRaise().

what is the effect that explicits the "throw exception" in the method signature

--the effects of case 1 and 2 are the same, why need to add the exception declaration in method signature?
//case 1
public void doSomething() throws Exception {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
//case 2
public void doSomething() {
//do Something
}
public void Caller() {
try {
doSomething();
} catch (Exception e) {
//handle the exception
}
}
reference:
what is the use of throws Exception
The throws declaration is used to declare which checked exceptions your method throws.
For instance, if I write this code:
public void doSomething() throws SQLException {
}
any code that calls this method must have a try/catch block for SQLException, Exception, or Throwable... or it can have its own throws declaration for one of those 3.
In this case, there is no difference, except that you're alerting the compiler to an exception that you're not going to be throwing.
It's also a bad idea to catch throw "Exception" - in both cases, you want to deal a particular exception that has a particular meaning. When you're catching, the only reason to use a try block is if you expect a particular exception, so you should catch that one. This way, if some unexpected exception comes up, you don't try to handle it the wrong way. (instead, your program fails, and you know there's a condition you have to deal with) When you're throwing, you want to throw a particular exception, either one you make up, or a standard one that has a known meaning, so the calling function knows what to deal with. For example, if your doSomething might throw an ArrayIndexNotFoundException if the widgets are not frobnicated, you might want to catch the ArrayIndexNotFoundException and throw a WidgetNotFrobnicatedException. Any time you throw an exception, your javadoc should specify exactly what circumstances will trigger that issue, so the user of your code has a chance to address this possible failure.
(there is one circumstance when I can see catching Exception, and that's if you want to fade to some graceful halt if things go wrong unexpectedly - in that case, in your catch block you'd log the issue, possibly alert a developer, and throw up some sort of "Sorry, error number 3542 has occurred, please restart the program" message.)
If your doSomething method, has the chance to throw an exception and you don't want to catch it, you should add this throws Exception on the method.
Unless it's an exception that you want to handle immediately in that method, it's good practice to use throws [specific Exception] so that the exception can be handled further up in the code.
It's somewhat commonplace to have a generic Throwable catch at the top that "gracefully crashes" in case something goes wrong.

Java Try Catch Block Size

This might be a weird question, but I still thought I would ask to get insights into this, and stop me from doing something wrong while I am coding.
Let's say I have a function func1(), inside which I call a function func2(). func2() throws an exception e1. And I want to catch this exception inside func1().
So does it matter whether I start a try block at the beginning of the function itself and end it at the end of func1() with the catch block, rather than just surrounding the part of the code where I call function func2().
I know from the coders perspective, where if an exception is thrown, he will be able to know exactly where the exception came from. If we ignore this, are there any other ill effects of just placing the whole method inside try-catch?
Edit - Code Fragment
So I am converting a JSON String to JSON Node. This operation throws an exception. But instead of surrounding this one statement with a try-catch block, I put the whole function inside the try block. It just looks cleaner to me. :)
public void storePublicData(String publicData, String twitterId) {
try {
Date date=new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String day = formatter.format(date);
BasicDBObject query = new BasicDBObject("date", day);
query.append("brand_id", twitterId);
JsonNode publicDataJsonNode;
publicDataJsonNode = JSONOperations.castFromStringToJSONNode(publicData);
DBObject document = BasicDBObjectBuilder.start()
.add("brand_id", twitterId)
.add("date", day)
.add("followers", publicDataJsonNode.get("followersCount").asText())
.add("tweets", publicDataJsonNode.get("tweetsCount").asText())
.get();
twitterCollection.update(query,new BasicDBObject("$set", document), true, false);
} catch (JSONParamsException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The biggest disadvantage is that you may also catch an exception you didn't intend to catch.
For instance, let's say you have a method that may throw a NullPointerException, and you can handle that case. (Such a method is probably badly written, but let's say it's a library method and you can't change it.) So, you catch the NPE:
void func1() {
try {
func2();
if (someString.equals("some value") {
someOtherFunction();
}
} catch (NullPointerException e) {
// handle func2()'s NPE somehow
}
}
There are two places a NPE could have been thrown within the try's body: from func2, or from someString.equals if someString is null. This code treats both the same way, which is probably a bug.
Generally speaking, in nearly all aspects of programming (variable scope, try-catch blocks, class members, etc), the smaller the scope is, the easier it is to reason about and the less likely you are to write bugs.
You can obviously use a try/catch block surrounding the entire body of the method, but confining it to the area that you are expecting an error adds readability to your code. I'm also fairly certain that they are very slow, and inefficient and there's no point to 'try' something where there's no possible IOException for example int i = 2 + 2;
I know from the coders perspective, where if an exception is thrown,
he will be able to know exactly where the exception came from
You nailed it right there: when you write a method you create a contract between you and the user. If you declare that the method throws an exception - it will be the responsibility of the user to catch and handle that exception. If it makes sense - you should do it (for example, throw an exception if you failed opening a connection to the DB). That said, in other cases, you might want to preform a fallback and just report to the user if the action was successful or not, in that case you can surround all the code inside method2 with try/catch and return a boolean value to save your users the extra coding of handling the exception.
well, if you have anything in funct1 after the call to funct2, that won't get executed if you place the whole method inside the try-catch.
im am citing Clean Code Book :
Error Handling Is One job, and functions should do one job.
Thus, a function that handles errors should do nothing else. This implies (as in the example above) that if the keyword try exists in a function, it should be the very first word in the function and that there
should be nothing after the catch/finally blocks.
so you should create a method that manages the exception , something like this:
public class Test {
public void doSomthing(){
// here i don't need to manage the exception because i have built parseDate(String date)
Date date = parseDate("10-17-2016");
}
private Date parseDate(String date){
Date result = null;
try {
result = new SimpleDateFormat().parse(date);//Throws Parse Exception
} catch (ParseException e) {
// Here you can:
//1) Throws other exception (Checked or Unchecked)
//2) Log the exception
// I think you should not re-throws the exception because
//is responsibility of this methods manage the exception
e.printStackTrace();
}
return result;
}
}

does throws exception leads the program to a pre written code

( patience requested as i'm new to programming )
when you add the phrase throws ABCexception in method declaration like this
public static void main(String[] args) throws ABCException {
}
does it mean that the you expect the method could generate an ABC exception and by writing throws ABCException ... when this exception occurs .. this exception will be caught and some prewritten code in java language will be executed corresponding to the ABCException. ?
thanks
throws declares that the method may throw the exception so the code that invoke this method must be prepare for it.
Being prepared for exception means that the code may catch the exception or re-throw it up.
Consider the constructor new FileInputStream(File pFile) which will create a FileInputStream from a File object. Since the file may not exist or not readable the constructor will throw FileNotFoundException (as declared).
So any code that call this constructor will either catch or rethrow it.
Catching it, the code will taking care of that exception by themself while rethrowing it, the code will let its caller take care of it.
Consider the following two codes:
Code 1: Catch -> Take care of it
public String readTextFile(File pFile) {
try {
FileInputStream FIO = new FileInputStream(pFile);
... // Do the reading and return
} catch (FileNotFoundException E) {
System.err.println("The file is not found");
}
}
Code 2: Throw -> Let the caller take care of ot
public String readTextFile(File pFile) throws FileNotFoundException {
FileInputStream FIO = new FileInputStream(pFile);
... // Do the reading and return
}
So the caller of readTextFile will have to catch or rethrow it too.
This mechanism ensures that someone have to take care of the exception in someway.
I hope I help.
The thows ABCException statement, before the function definition starts in earnest is just to indicate that this function may throw such an exception.
The actual throwing of the exception would happen within the code of the function. With code like the following (note the lack of an 's' at the end of "throw")
throw new ABCException();
The exceptions are then passed on "up" through the chain of the program logic that called this function this function, until one these "catches" the exception and deals with it. In case the exception "bubbles back" all the to the main() function, and if said exception isn't caught there either, a default handler deals with it, typically by printing out the exception to stderr/stdout and halting.
The way this exception could be caught would be with a try-catch construct, as in:
try
{
// do some stuff if needed
xy = fct(); // this fct may throw the ABCExeption...
// do more stuff as well
}
catch (ABCException e)
{
// for debugging you can do this
e.printStackTrace();
// otherwise you could deal with this exception as desired.
}
In re-reading the question, I noted that the function which is declared with throws ABCException and that is a bit odd, because main is the first method in the chain of function calls, meaning that there is nothing before main() which could catch an exception (other than the default exception handler of the Java Runtime, which wouldn't do anything specific for ABCException; it would just "dump it" to the console (or elsewhere for GUI-based apps) like any other exception.

Java -- Exception must be thrown, but how?

I am getting an error in NetBeans saying I must throw an SQLException in this method:
private void displayCustomerInfo(java.awt.event.ActionEvent evt)
{
int custID = Integer.parseInt(customerID.getText());
String info = getCustomerInfo(custID);
results.setText(info);
}
This method is created by NetBeans so it is not allowing me to edit the signature and throw the exception. This is why I created the getCustomerInfo() method. This method does throw the exception, because it uses a method to retrieve information from a database about a customer.
public String getCustomerInfo(int cid) throws SQLException
{
Customer c = proc.getCustomer(cid);
// get info
return "info";
}
The getCustomer method also throws the exception and proc.java compiles.
The exact error is
unreported exception java.sql.SQLException; must be caught or declared to be thrown
In general, if your code needs to throw a type of Exception that the signature doesn't support, and you have no control over the interface, you can catch and rethrow as a type the interface does support. If your interface doesn't declare ANY checked exceptions, you can always throw a RuntimeException:
private void displayCustomerInfo(java.awt.event.ActionEven evt)
{
try
{
int custID = Integer.parseInt(customerID.getText());
String info = getCustomerInfo(custID);
results.setText(info);
}
catch (SQLException ex)
{
throw new RuntimeException(ex); // maybe create a new exception type?
}
}
You almost definitely want to create a new Exception type that extends RuntimeException, and have your client code catch that exception. Otherwise, you run the risk of catching ANY RuntimeException, including NullPointerException, ArrayIndexOutOfBoundsException, etc., which your client code probably can't handle.
Read the error message again, it gives you two choices.
You must either declare the exception as thrown (which you cannot do) or catch the exception. Try the 2nd choice.
You need to put a try/catch block around your call to getCustomerInfo(), like so:
private void displayCustomerInfo(java.awt.event.ActionEvent evt)
{
int custID = Integer.parseInt(customerID.getText());
try {
String info = getCustomerInfo(custID);
} catch (SQLException sqle) {
// Do something with the exception
}
results.setText(info);
}
A couple good options for handling the exception might be: logging the exception and the details used to get it, or using it as a signal to retry the connection request. Alternatively, as Outlaw Programmer shows, you could re-throw the Exception as a RuntimeException of some kind, which removes the requirement of checking.
It does not say you must throw it. It says you can catch it. So use a try/catch block and handle it.
try {
...
}
catch (SQLException e) {
System.out.println("Exception happened! Abort! Abort!");
e.printMessage(); //Not sure if this is the correct method name
}
NetBeans generated components have un-modifiable code, and I'm guessing that it is generated as a part of the gui builder. I'd ask if this was the case, but I can't comment yet. If you select a generated object in the GUI editor, on the right there is a tab "code" that can be used to modify the grayed out area of the code.
Here:
I've come across this problem... been puzzled for the past 2 days.. then I open the source (.java file) with sublime, change the code, save, and it works wonders... I'm laughing when I see this works... think outside the box really works...

Categories

Resources