Reputation: 29
I want to test my java code using Junit test framework. In my source code I use try and catch block to handle exceptions. In my test method I want to test this method. If my source code return some exceptions and if it matches in my test method, My test will pass otherwise fail. But my code does not pass this test.
I found a way to figure it out but I want to use try and catch block. Also I will share it.
NOT WORKING My Source Code(I want to test this method)
public boolean isCreateAccount(String amount) {
try {
Double balance = Double.parseDouble(amount);
if(balance < 0)
throw new Exception();
} catch (Exception e) {
System.out.println("WARNING: Invalid amount!");
}
return false;
}
This is my test method in JUnit
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testCreateAccountInvalidAmount() {
expectedException.expect(Exception.class);
accountServices.isCreateAccount("-100");
}
WORKING This way is working but I want to use try and catch block My Source Code(I want to test this method)
public void isCreateCheckingAccount(String amount) {
Double balance = Double.parseDouble(amount);
if(balance < 0)
throw new Exception();
}
This is my test method in JUnit
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testCreateAccountInvalidAmount() {
expectedException.expect(Exception.class);
accountServices.isCreateAccount("-100");
}
Upvotes: 0
Views: 1214
Reputation: 29
I figured it out this problem. Thank you for your help guys. I share my solution here. I hope it helps if you have this kind of problem.
// this code in my service layer...
@Override
public boolean isCreateAccount(String amount) {
try {
isValidAmount(amount);
double balance = Double.parseDouble(amount);
createAccount(balance);
return true;
} catch(NullPointerException e) {
log.warn("WARNING: Empty Amount!");
System.out.println("\nWARNING: Empty Amount!");
} catch (NumberFormatException e) {
log.warn("WARNING: Invalid amount!");
System.out.println("\nWARNING: Invalid amount!");
} catch (NegativeAmountException e) {
log.warn("WARNING: Amount must have a positive number!");
System.out.println("\nWARNING: Amount must have a positive number!");
} catch (InsufficientAmountException e) {
log.warn("WARNING: Not enough money to open a checking account!");
System.out.println("\nWARNING: Not enough money to open a checking
account!");
}
return false;
}
// this code in my service layer...
@Override
public void isValidAmount(String money) {
if(money == null || money.length() == 0) {
throw new NullPointerException("Empty Amount");
}
double amount = 0.0D;
try {
amount = Double.parseDouble(money);
} catch (NumberFormatException e) {
throw new NumberFormatException("Invalid Amount");
}
if(amount < 0.0D) {
throw new NegativeAmountException("Negative Amount");
}
if(amount < 25.0D) {
throw new InsufficientAmountException("Insufficient Amount");
}
}
//This code in my Test Class in Junit
@Test
public void testCreateCheckingAccountNullAmount() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("Empty Amount");
accountServices.isValidAmount("");
}
@Test
public void testCreateCheckingAccountInvalidAmount() {
expectedException.expect(NumberFormatException.class);
expectedException.expectMessage("Invalid Amount");
accountServices.isValidAmount("a100");
}
@Test
public void testCreateCheckingAccountNegativeAmount() {
expectedException.expect(NegativeAmountException.class);
expectedException.expectMessage("Negative Amount");
accountServices.isValidAmount("-10");
}
@Test
public void testCreateCheckingAccountInsufficientAmount() {
expectedException.expect(InsufficientAmountException.class);
expectedException.expectMessage("Insufficient Amount");
accountServices.isValidAmount("10");
}
Upvotes: 1
Reputation:
This will do what you want:
public boolean isCreateAccount(String amount) throws Exception {
Double balance = Double.parseDouble(amount);
if (balance < 0) {
System.out.println("WARNING: Invalid amount!");
throw new Exception();
}
return false;
}
Returning false doesn't make much sense though.
If you really want that try catch block:
public boolean isCreateAccount(String amount) throws Exception {
try {
Double balance = Double.parseDouble(amount);
if (balance < 0) {
System.out.println("WARNING: Invalid amount!");
throw new Exception();
}
} catch (Exception e) {
throw e;
}
return false;
}
And these basic tests works for both versions:
public class AccountTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testCreateAccountInvalidAmount() throws Exception {
Account accountServices = new Account();
expectedException.expect(Exception.class);
accountServices.isCreateAccount("-100");
}
@Test
public void testCreateAccountZeroAmount() throws Exception {
Account accountServices = new Account();
assertFalse(accountServices.isCreateAccount("0"));
}
@Test
public void testCreateAccountValidAmount() throws Exception {
Account accountServices = new Account();
assertFalse(accountServices.isCreateAccount("1"));
}
}
Upvotes: 0
Reputation: 102902
Look at your method. It has the following behaviours:
If amount is negative or not a number, it prints something to sysout (which is bad; you should not mix responsibilities like this; your Account tool is surely not also your UI layer, but that's a secondary issue). Otherwise it prints nothing.
Then, regardless of what you passed in, it prints false.
So, the observable behaviour of this method is that it returns false, and that it prints something to sysout.
Testing that it returns false is trivial; assertFalse(services.isCreateAccount("100")
will do it (though, presumably, the fact that your method always returns false is in fact an error).
Testing that it prints something to sysout is complicated. That's because of the fundamental issue that you shouldn't be printing anything there. If output is part of the point, then instead of printing to System.out
, pass along some output abstraction (perhaps a java.io.PrintWriter
) to AccountServices
so that you can pass some variant of that as part of the test; a variant that can be configured to check if some expected output shows up here.
You seem to be under the impression that this method throws something. It doesn't - it catches something. In junit, saying: "I expect this exception" means you expect it to fall out of the method, i.e. the opposite: That the method does NOT catch that, or even, that the method explicitly throws that.
Upvotes: 0