I have to write Junit test for the catch block. But I am not able to identify what should I assert here. Since the func() is only catching the exception and not throwing anything I cannot assert using Assertions.assertThatExceptionOfType(). I am new to Junit testing so cannot think of anything else. Any possible way to test the type of exception received by catch block.
Method
public void func() {
try {
int x = solve();
} catch(Exception1 e) {
log.warn("error", e);
} catch(Exception2 e) {
log.warn("error", e);
}
}
private int solve() throws ExceptionName {
//do something...
throws new Exception("error occured");
...
}
You can change the visibility of solve() method and test it with all exception cases. For example change it to default
int solve() throws ExceptionName {
Put tests in the same package as class with this method so that it could be access from test.
UPDATE
The best way would be to change the code to be more testable as it was shown above.
In order to not change the code you can use the way from this answer. It can be tricky. With Mockito and PowerMockito you can control when Exception1 or Exception2 are creating. Based on this you will know which catch statement was executed.
In test code it could be like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ Exception1.class, Exception2.class, MyClass.class })
public class TestClass {
#Before
public void setup() {
Exception1 cutMock = Mockito.mock(Exception1.class);
PowerMockito.whenNew(Exception1.class)
.withArguments(Matchers.anyString())
.thenReturn(cutMock);
}
#Test
public void testMethod() {
// prepare
MyClasss myClass = new MyClass();
// execute
myClass.func();
// checks if the constructor has been called once and with the expected argument values:
String value = "abc";
PowerMockito.verifyNew(Exception1.class).withArguments(value);
}
}
Related
I'll begin with a code example; I have to test a function, which handles data-packets. In this function, the data-packet is opened and when it doesn't contain all expected data, an InvalidParameterExeption is thrown which is logged.
public void handleData(dataPacket) {
try {
analyseData(dataPacket);
} catch (InvalidParameterException e) {
e.printStackTrace()
}
}
So, if everything goes well, my exception is printed in my terminal.
But how can I test this? I can't use this: (because the exception is caught)
#Test(expected = InvalidParameterExeption.class)
public void testIfFaultyDataPacketIsRecognised {
handleData(faultyDataPacket);
}
How can I test that the InvalidParameterExeption is thrown?
You won't catch exceptions that are not thrown. Just test the 'throwing exception' method instead of the 'exception catching' one
#Test(expected = InvalidParameterExeption.class)
public void testIfFaultyDataPacketIsRecognised() {
analyseData(faultyDataPacket);
}
Ideally you should catch and rethrow the exception.But if you dont want to do that then Why not get catch the exception in test case as expected?
#Test
public void testIfFaultyDataPacketIsRecognised () {
try {
handleData(faultyDataPacket);
Assert.fail("Fail! Method was expected to throw an exception because faulty data packet was sent.")
} catch (InvalidParameterException e) {
// expected
}
}
This is something that's been bugging me for a while with regards to Program Flow.
I wanted to know if it's possible to catch an error from a Method in order to stop it from executing the Method that would normally follow it like the example bellow that I can't get to work.
public class MyClass {
public static void main(String[] args) {
// this method catches an exception and stops running
method01();
// this method will continue anyway which I don't want
method02();
};
};
I would normally have a static int variable that will initialize as 0 when the program is run and then if a method ever catches an exception it will increment that int and each method will only run if the int is 0.
This works but I was just wondering if I could replace the int shindig with exception handling.
Can you try:
try {
method01()
} catch (final Exception e) {
// do something
return; ///stop processing exit
}
the method01 will throw Exception:
private void method01() throws Exception {
// something
}
If you only want to terminate the whole program in case of an exception you just need to throw a RuntimeException without any further declaration. There are also specialized sub classes for explicit types of exceptions, like NullPointerException or IllegalStateException. See the "Direct Known Subclasses" section in the JavaDoc.
public class MyClass {
public static void main(String[] args) {
method01();
method02(); //method02 won't be called in case of an exception
}
private static void method01() {
// ...
if (true) // something goes wrong
throw new RuntimeException();
// further code won't be executed in case of an exception
}
private static void method02() {
System.out.println("method02 called");
}
}
Optionally it is possible to handle the exception with a try-catch-block:
public static void main(String[] args) {
try {
method01();
method02(); // method02 won't be called in case of an exception
} catch (Exception e) {
System.err.println("something went wrong");
}
}
// other code keeps unchanged...
If you want to enforce exception handling, you have to throw a subclass of Exception that is not derived from RuntimeException. But those exceptions have to be declared within the method Signature.
private static void method01() throws IOException {
throw new IOException();
}
You put method01 and method02 in to same try block:
public class MyClass {
public static void main(String[] args) {
try {
// This method catches an exception and stops running.
method01();
// This method will not continue if method01 have exception.
method02();
} catch (Exception e) {
e.printStackTrace();
}
}
// declare method01, method02, others...
}
Notice: You have mistakes at the end of code block ( }; }; )
Depends on what your method really does.
If your program should continue working also when an exception arise (e.g. NumberFormatException when parsing an input or in general a checked exception) a lot of people will suggest you to not use exception for flow control, but IMHO in very well defined cases (like NumberFormatException) the flow CAN be controlled by try catch statements and exceptions, it's really up to you.
A way to do so is to use the method returned parameter (also #Nikola answer works in this way, the point is to use the catch part of a try catch as flow control):
public class MyClass {
public static void main(String[] args) {
if(method01()) method02();
};
};
public boolean method01(){
try{
//some business
}catch(MyCheckedException e){
e.printStackTrace();
return false;
}
return true;
}
NB: You should use this approach only in well defined situations! If a file CAN be absent in a directory while opening it (checked FileNotFoundException), you COULD use this approach. If the file SHOULD be there and its not, the exception MUST stop the program.
I saw people using "throws Exception" in tests, but I never do. Should I worry? I never had any issues with that. What's the difference?
#Test()
public void test() throws Exception
{
//Do something
}
or
#Test()
public void test()
{
//Do something
}
If the code you are testing throws an exception, you must handle it in some way. Either by declaring a "throws Exception" in the method signature, or by using try-catch.
If the code you are calling in the method does not throw any exceptions, then you dont need either of those. The compiler will let you know if you need to catch an exception in some way.
Also note that you can do tests that makes sure an exception is thrown, see this answer
junit will mark a test as being in "error state" if an exception is thrown from that method. For most usecases, this is essentially the same as failing a test (in the sense that a test that completed in error state did not succeed). A lot of test authors don't like the hassle (or the code-uglification) associated with handling checked exceptions.
E.g., Consider a test that should run a couple of methods and assert the end state of an object:
public class SomeTest
SomeObject so;
#Before
public void setUp() {
so = new SomeObject();
}
#Test
public void TestSomeFlow() {
try {
so.init();
// must catch in order to avoid a compilation error
} catch (InitExceptionIDontCareAbout e) {
fail ("init failed");
}
try {
so.doSomething();
// must catch in order to avoid a compilation error
} catch (SomeOtherExceptionIDontCareAbout e) {
fail ("doSomething failed");
}
assertTrue ("doSomething didn't work", so.isSomethingDone());
}
}
Now consider how much cleaner the code looks without exception handling:
public class SomeTest
SomeObject so;
#Before
public void setUp() {
so = new SomeObject();
}
// Any exception throwm will mean the test did not succeed
#Test
public void TestSomeFlow() throws Exception {
so.init();
so.doSomething();
assertTrue ("doSomething didn't work", so.isSomethingDone());
}
}
Functionally, there is no difference. It only means that the compiler wont complain if you throw a non-RuntimeException. Since JUnit will catch any exception thrown by the test method anyway, it does not really matter.
However, it is usually considered a better practice to catch the Exception yourself and use the fail method of JUnit, in which case you do not need the throws clause.
I'm writing my own JUnit Assert? How do I test it?
I know how to feed it something that will pass and something that will make it fail, but how do I write a JUnit test for those things?
The custom assert will look something like:
public static void assertSomething() {
if (!something()) {
fail("Expected something, but ...");
}
}
How can I catch that fail?
fail() throws a junit.framework.AssertionFailedError, which you could catch in a unit test of your assertion method, if you like.
Example:
#Test(expected = AssertionFailedError.class)
public void testMyAssertFails() {
assertSomething("valueThatWillFail");
}
#Test
public void testMyAssertPasses() {
assertSomething("valueThatPasses");
//if you reach this line, no failure was thrown
}
I have a method that looks similar to the following:
public void myMethod(MyClass c)
{
if (c == null)
{
return;
}
try
{
c.someMethod();
}
catch (SomeException e)
{
// log the exception, possibly re-throw
}
}
I am trying to find a way to set up a mock instance of the MyClass parameter c such that it returns a value of null for itself, and that c.someMethod() is never called. My unit test looks like this:
#Test
public void Test_myMethod_With_Null_MyClass_Does_Not_Call_someMethod()
{
Mockery mockery = new Mockery()
{{
setImposteriser(ClassImposteriser.INSTANCE);
}};
final MyClass mockMyClass = mockery.mock(MyClass.class);
try
{
mockery.checking(new Expectations()
{{
oneOf(mockMyClass).equals(null);
will(returnValue(true));
never(mockMyClass).someMethod();
}});
}
catch (Exception e)
{
logger.fatal(e);
fail("Exception thrown in test.");
}
Util.myMethod(mockMyClass);
}
Basically, i'm setting up a mock instance of MyClass, and setting the expectations on it that when its value is tested against the null value, it will return true, and that the method someMethod() is never called.
Right now, the test is failing, as jMock says that it's not possible to override methods provided by the Object class (the equals(null) part).
Is there a way to do this with jMock? Does this pattern make sense? Is this a valid test? If not, does anyone have any suggestions on how to test this?
I do not think you can test this code using only JMock.
I would test this by passing in null directly. If no exceptions are thrown or logged, you know that your code worked as expected.#Test
public void Test_myMethod_With_Null_MyClass_Does_Not_Call_someMethod()
{
Util.myMethod(null);
//no exception should be thrown.
}
If you wanted to make it more explicit, you could wrap the myMethod(null) call in a try/catch block, but that is not necessary except to clarify the failure reason when there is a failure.
public void Test_myMethod_With_Null_MyClass_Does_Not_Call_someMethod()
{
try
{
Util.myMethod(null);
}
catch( ExpectedException e )
{
fail( "Should not have thrown exception: " + e.getMessage() );
}
}
This is a sufficient test because you know that if c is null then c.something() of course cannot be called.
Mocks are supposed to be used to test how an object interacts with its collaborators. If there is no collaborator, then there's nothing to mock. Passing in a null is simpler and more expressive.