I have a method with a handled exception:
public boolean exampleMethod(){
try{
Integer temp=null;
temp.equals(null);
return
}catch(Exception e){
e.printStackTrace();
}
}
I want to test it
public void test_exampleMethod(){}
I have tried
#Rule
public ExpectedException expectedException=ExpectedException.none();
public void test_exampleMethod(){
expectedException.expect(JsonParseException.class);
exampleMethod();
}
but that doesnt work because the exception is handled inside.
I also tried
#Test(expected=JsonParseException.class)
but same issue...the exception is handled
I know that I can just do
assertTrue(if(exampleMethod()))
but it will still print the stack trace to the log. I would prefer clean logs...Any suggestions?
You cannot test what a method is doing internally. This is completely hidden (unless there are side effects, that are visible outside).
The test can check that for a specific input the method returns a expected output. But you can not check, how this is done. So you have no way to detect if there was a exception that you have handled.
So: either don't handle the exception (let the test catch the exception), or return a special value that tells you about the exception.
Anyway, I hope your real exception handling is more sensible than in your example.
If the method does not throw an exception you cannot expect to get one!
Below an example how write a Junit Test for a method that throws an Exception:
class Parser {
public void parseValue(String number) {
return Integer.parseInt(number);
}
}
Normal test case
public void testParseValueOK() {
Parser parser = new Parser();
assertTrue(23, parser.parseValue("23"));
}
Test case for exception
public void testParseValueException() {
Parser parser = new Parser();
try {
int value = parser.parseValue("notANumber");
fail("Expected a NumberFormatException");
} catch (NumberFormatException ex) {
// as expected got exception
}
}
Related
private static String getToken(HttpClient clientInstance) throws badcredentailsexception{
try{
// some process here throws IOException
}
catch(IOexception e){
throw new badcredentailsexception(message, e)
}
}
Now I need to write Junit test for the above method, My Junit code for above function is below
#Test(expected = badcredentailsexception.class)
public void testGetTokenForExceptions() throws ClientProtocolException, IOException, NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Mockito.when(mockHttpClient.execute(Mockito.any(HttpPost.class))).thenThrow(IOException.class);
// mocked mockHttpClient to throw IOException
final Method method = Client.class.getDeclaredMethod("getToken", HttpClient.class);
method.setAccessible(true);
Object actual = method.invoke(null, mockHttpClient);
}
But this test is not being passed, any improvements??
Can we check the exception thrown by private method from junit ??
First of all, it is an antipattern to test a private method. It is not part of your API. See the already linked question: Testing Private method using mockito
To answer your question: When invoking a method via Reflection and the invoked method throws an Exception, the Reflection API wraps the Exception into an InvocationTargetException. So you could catch the InvocationTargetException and inspect the cause.
#Test
public void testGetTokenForExceptions() throws Exception {
HttpClient mockHttpClient = mock(HttpClient.class);
when(mockHttpClient.execute(any(HttpPost.class))).thenThrow(IOException.class);
Method method = Client.class.getDeclaredMethod("getToken", HttpClient.class);
method.setAccessible(true);
try {
method.invoke(null, mockHttpClient);
fail("should have thrown an exception");
} catch (InvocationTargetException e) {
assertThat(e.getCause(), instanceOf(BadCredentialsException.class));
}
}
You couldn't test private methods with JUnit or even with Mockito framework.
You could find more details in this question: Testing Private method using mockito
If you really need to test this private method, you should use PowerMock framework.
I try to test my Exception JUnit and the test doesn't pass I have this error trace :
org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnitAndHigherRunnerImpl.java:37)
and
org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
and here is my code :
PatientEntityFacade pef = new PatientEntityFacade();
Mockito.when(pef.findByNumber(5555)).thenReturn(patientEntity);
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void shouldThrow() throws PatientNotFoundException
{
thrown.expect(PatientNotFoundException.class);
thrown.expectMessage("personalized exception no patient found");
try {
pef.findByNumber(5555);
} catch (com.patient.facade.PatientNotFoundException e) {
e.printStackTrace();
}
}
If you watn to test your Exception, then do it the right way.
Define when Exception should be thrown.
in #BeforeClass if every Method should
in #Test-method if only this Method should throw it.
Notice, that you can use any(X.class) if other methods got other values for it.
DonĀ“t try-catch in unit-tests.
Catch it this way and if there is no Exception, the test will fail.
#Test(expected = PatientNotFoundException.class)
public void shouldThrow()
pef.findByNumber(5555);
}
I have the following method:
public Object method(){
try
{
privatevoidmethod1();
privatevoidmethod2();
}
catch(Exception e)
{
Log.debug(e);
}
return object;
}
How do I force the exception so I can test the debug call?
Leaving aside how you'd test the debug call, you'd normally trigger an exception by providing suitable inputs such that an exception would be created/thrown. If that's not suitable, the alternative is to provide a substitute (mocked) component that has been configured/written to throw an exception e.g.
public MyClass(MyInjectedComponent component) {
this.component = component;
}
and you'd provide for your test an implementation of MyInjectedComponent that will throw an exception (for testing purposes). The approach of injecting components into other components is called dependency injection and worth investigating.
I'd normally use a mocking framework for this (e.g. Mockito or similar). However a trivial implementation of the above could be:
public class MyImplementationForTesting extends MyInjectedComponent {
public void method() throws Exception {
throw new Exception();
}
}
I'm recently digging into the source code of JUnit-4.11, what confuse me is that the seemingly redundant Protectable interface. the declaration is as follows:
public interface Protectable {
public abstract void protect() throws Throwable;
}
In the TestResult class, there is a void run(final TestCase test) method, in which a anonymous Protectable instance is realized as follows:
protected void run(final TestCase test) {
startTest(test);
Protectable p = new Protectable() {
public void protect() throws Throwable {
test.runBare();
}
};
runProtected(test, p);
endTest(test);
}
runProtected method is as follows:
public void runProtected(final Test test, Protectable p) {
try {
p.protect();
} catch (AssertionFailedError e) {
addFailure(test, e);
} catch (ThreadDeath e) { // don't catch ThreadDeath by accident
throw e;
} catch (Throwable e) {
addError(test, e);
}
}
As we can see, what runProtected does is just executing test.runBare();, so is there any sense to the existence of Protectable interface? Why can't we just write code like below.
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
To answer your final question first, you can't use
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
because it won't do what you want. JUnit manages asserts using exceptions, specifically AssertionFailedError. So, Assert.assertEquals() throws an AssertionFailedError when the two values aren't equal. So, in the above method, the endTest(test) won't get called if there is an assertion failure, which means the correct events (failure/error of the test) won't get fired, and tearDown() won't get executed.
The Protectable interface is there to give a more generic interface to the runner, so that you don't have to hand a TestCase to the method, to allow different actions.
As an aside, this is part of the package junit.framework.*, which is JUnit 3. JUnit 4 is where it's at, and if you want to learn, look more in the org.junit.* packages.
It seems to handle thrown exceptions in specific way :
Call addFailure for assertion exception (your test failed), addError for other exception (your test is not well coded)
This interface is to protect the TestCase by adding Throwable.
so junit could run any testcase safely.
The Throwable class is the superclass of all errors and exceptions in the Java language.
I want to know that whether this test case should pass or fail
beacause
expected = IndexOutOfBoundsException.class
and actually it is throwing Arithmatic exception. can anyone explain?
#Test(expected = IndexOutOfBoundsException.class)
public void testDivideNumbers()throws ArithmeticException{
try{
double a = 10/0;
fail("Failed: Should get an Arithmatic Exception");
}
catch (ArithmeticException e) {
}
}
To test that the correct exception is thrown you should not have the test method throw the exception but just have the test itself result in the thrown exception.
So if ArithmeticException is expected then the test should be:
#Test(expected = ArithmeticException.class)
public void testDivideNumbers() {
double a = 10/0;
}
It should fail because it doesn't throw any exception; the ArithmeticException is caught and swallowed by the catch block.
This test is expecting to get an IndexOutOfBoundsException thrown. Because that does not happen in the test, the test fails. You can "fix" the test like this:
#Test(expected = IndexOutOfBoundsException.class)
public void testDivideNumbers() {
try {
double a = 10/0;
Assert.fail("Failed: Should get an Arithmetic Exception");
}
catch (ArithmeticException e) {
// Assert that this exception is thrown as expected
Assert.assertEquals("/ by zero", e.getMessage());
}
throw new IndexOutOfBoundsException();
}
You should not leave the catch block empty. You should always put some assert in it proving that the fail() didn't happen and the catch did happen and, importantly, happened for the reason you expected.