Handling a custom exception without changing the test class (java) - java

I need to throw a couple times a custom exception. A test class is checking if my solution works but I'm not allowed to make any changes to this class which leads me to my problem.
I simplified the problem here, because the whole code is not needed here
public class Test{
public static final String s = "0test";
#Test
public void testZero(){
Solver sol = new Solver(Parser.run(s));
//IntelliJ is underlining "run" because "Unhandled exception: ParseException", a
//simple solution could be adding "throws ParseException" in the head, but I'm not
//allowed to change the test class
}
}
public class Parser{
public static Pars run(String input) throws ParseException{
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
}
}
public class ParseException extends Exception{
public ParseException(String mess){
super(mess);
}
}

I'm not allowed to make any changes to this class which leads me to my problem.
There is no way that you can throw an Exception to the Test class without catching it over there.
BUT you can prematurely just catch it inside the Parser#run(String input).
Instead of this:
public static Pars run(String input) throws ParseException{
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
}
You could (as I said) catch it in the method instead.
public static Pars run(String input) {
try {
if(input.charAt(0) == '0'){
throw new ParseException("...");
}
} catch (ParseException e) {
// System.out.println(e.toString());
// Just handle it over here if you can't edit Test.java ...
}
}

I have found the solution for my problem.
In my ParseException class, I need to change it to:
public class ParseException extends IllegalArgumentException{...}
Further into the task, the test class didnt accept my exception because there was a IllegalArgumentException exspected.
Changing it into "extends IllegalArgumentException" solves the problem, so I dont need "throws ParseException" in the headings and no try,catch statements

Related

how to test my custom exception with unit test

Hello I have wrote a test cases for my logic and all these are working nicely. however, I have no idea how to test my custom exceptions. My code below;
#Component
public class PlaneFactory {
public Plane getPlane(String planeType) {
if (StringUtils.isBlank(planeType)) {
throw new PlaneTypeNotFoundException();
}
if (planeType.equalsIgnoreCase("lightJet")) {
return new LightJet();
} else if (planeType.equalsIgnoreCase("midJet")) {
return new MidJet();
}
else {
throw new InvalidPlaneTypeException();
}
my custom exceptions below;
PlaneTypeNotFoundException class below;
public class PlaneTypeNotFoundException extends RuntimeException {
private static final long serialVersionUID = 4314211343358454345L;
public PlaneTypeNotFoundException() {
super("You have not enter anything to check a plane");
}
}
InvalidPlaneTypeException below;
public class InvalidPlaneTypeException extends RuntimeException {
public InvalidPlaneTypeException() {
super("You need to enter one of following plane types : {LightJet, MidJet}");
}
}
which methods are suitable to use ? I mean in this scenario should I use assertThrows or just use expected annotations ?
for PlaneTypeNotFoundException I have tried something below which it did not work
#Test
public void testPlaneFactory_isEmptyOrNull_ThenReturnException() {
String planeType = "";
LightJet lightJet= (LightJet) planeFactory.getPlane(planeType);
assertThrows(PlaneNotFoundException.class, () -> lightJet.getType().equalsIgnoreCase(planeType), "You have not enter anything to check a plane");
}
If I follow your code correctly then the executable lambda in assertThrows() should be the code that you expect to generate the exception:
public void testPlaneFactory_isEmptyOrNull_ThenReturnException() {
assertThrows(PlaneNotFoundException.class, () -> planeFactory.getPlane(""));
}
If it does throw an exception then the test should pass.
A test for the second case would be:
void testInvalidPlaneType() {
assertThrows(InvalidPlaneTypeException.class, () -> planeFactory.getPlane("doh"));
}

How to map a list of Java exceptions to customer visible error codes

I'm designing a Java exception handling mechanism for a 2 component system {front-end, back-end}. The back-end will generate exceptions by using Exception classes for different error conditions. Front-end has to map those exception classes to a customer visible error code. This list of Exception classes can be pretty big and may continue to increase in size. What is the best way to map those Exception classes to customer visible error codes?
I could create a Map<Class, Integer> MAP_EX_CLASS_TO_ERROR_CODE and keep it updated, but is it the right/scalable way to map exceptions?
------- Edits after receiving initial set of answers, see Comments below ----
I want to represent similar types of exceptions, or exceptions that demand similar handling with one exception class. For e.g. UserExceptions can be:
RESOURCE_NAME_TOO_LONG
RESOURCE_NOT_FOUND
RESOURCE_NOT_OWNED
...
and InternalExceptions can be:
SERVER_UNAVAILABLE
REQUEST_TIMEOUT
...
If I make an enum for all these error codes, then is it still useful to implement the grouping? I wanted to do the grouping instead of defining one single class for checked exceptions because it'll force me to pay attention to the catch-ing of exceptions every time I add a new line of code that throws a different checked exception than existing code.
for e.g.
public enum ECodes {
RESOURCE_NAME_TOO_LONG(/*number*/0, UserException.class),
RESOURCE_NOT_FOUND(1, UserException.class),
RESOURCE_NOT_OWNED(2, UserException.class),
SERVER_UNAVAILABLE(3, InternalException.class),
REQUEST_TIMEOUT(4, InternalException.class);
// constructor and stuff
}
public class Prot1ExceptionMapper {
static Map<Ecode, /*CustomerCode*/Integer> MAP_EX_CLASS_TO_ERROR_CODE = new HashMap<>();
static {
MAP_EX_CLASS_TO_ERROR_CODE.add(Ecode.RESOURCE_NAME_TOO_LONG, PROT1_CUSTOMER_CODE1);
// Other mappings here
}
public static Integer map(Ecode ecode) {
// Lookup ecode
}
}
public class Prot2ExceptionMapper {
static Map<Ecode, /*CustomerCode*/Integer> MAP_EX_CLASS_TO_ERROR_CODE = new HashMap<>();
static {
MAP_EX_CLASS_TO_ERROR_CODE.add(Ecode.RESOURCE_NAME_TOO_LONG, PROT2_CUSTOMER_CODE1);
// Other mappings here
}
public static Integer map(Ecode ecode) {
// Lookup ecode
}
}
public class UserException extends Exception {
public UserException(ECodes ecode, String message) {
assert ecode.class == UserException.class;
}
}
public class InternalException extends Exception {
public InternalException(ECodes ecode, String message) {
assert ecode.class == UserException.class;
}
}
class DummyClass {
public void doFirstJob() throws UserException {}
public void doSecondJob() throws InternalException {}
}
class Protocol1MainClass {
public static void main(final String[] args) {
try {
doFirstJob();
doSecondJob();
} catch (UserException e1) {
// Do UserException specific stuff
throw Prot1ExceptionMapper.map(e1);
} catch (InternalException e2) {
// Do InternalException specific stuff
throw Prot1ExceptionMapper.map(e2);
}

Using jmockit to mock constructor that throws error: NoClassDefFoundError

Jmockit is very powerful, but sometimes I cannot understand what it does behind the scene, so I have a question regarding jmockit. Hopefully the more experienced programmers on here could help shine some light on this situation :)
I have the following two classes in two separate files:
public class SmallClass {
String a;
SmallClass(String arg) throws Exception {
a = arg;
}
public String getString() {
return a;
}
}
And
public class BigClass {
private static final SmallClass smallClass;
static {
try {
smallClass = new SmallClass("dummy");
} catch (Exception e) {
throw new IllegalStateException("Could not initialized", e);
}
}
public static String getString() {
return smallClass.getString();
}
}
Now, I have a class to test BigClass:
public class BigClassTest {
#Test
public void testGet() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
}
}
If I run each of these independently, then they each passes. But if I run the whole test file, then the first test fails with:
java.lang.NoClassDefFoundError: Could not initialize class BigClass
I also tried tearing down the mock after each test like this, but it doesn't help:
public class BigClassTest {
MockUp<SmallClass> smallClassMockUp;
#Test
public void testGet() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
smallClassMockUp.tearDown();
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
smallClassMockUp.tearDown();
}
}
Any help would be appreciated. Thank you in advance!
The occurrence of NoClassDefFoundError, in a case like this, is not because the class wasn't found by the JVM (it was), but because its static initialization has failed (by throwing an exception or error from the execution of a static initializer). Once this happens, the class is left in an invalid/uninitialized state and cannot be used in the same JVM instance anymore.
For reference, see the "Initialization of classes and interfaces" section in the JLS.
Also, note that the order in which tests execute is not necessarily the textual order they appear in the test class. Here, testException (the second test) runs first. So, when testGet runs, the class is invalid and the JVM throws the error.

JUnit testing with annotations

Hey all I am trying to get these Unit tests to fail but can't it uses annotations, which is new to me. Any ideas would be great!
I have been trying all sorts of ways to get them to fail by either setting the test class variables to null, or trying to use if/else statements in the minimum test, but they always come out passing. Is this correct?
public class ValidationServiceTest extends BaseServiceTest {
ValidationService validationService;
ValidationException ve;
TestDto test;
Field f;
#Before
public void setup() {
validationService = new ValidationService();
ve = null;
}
#Test
public void validateNotNull(){
try {
validationService.validate(ve, test.xx);
assertNotNull("testing notNull()", ve);
} catch (Exception e) {
}
}
#Test
public void validateMin(){
try {
validationService.validate(ve, test.xy);
if(test.xy > f.min()){
assertTrue("testing min()" , test.xy > -1);
}
} catch (Exception e) {
}
}
public class TestDto{
#Field(notNull=true)
public Integer xx = null;
#Field(min=2)
public Integer xy = -5;
}
}
Do not catch Exception, mark test method with throws Exception instead.
The test field is never initialized in your test, which means it's null. This causes NullPointerException whenever you try to access fields of test. The assertion line is skipped and exception is suppressed in the catch clause. Removing the try/catch block and marking test method with throws Exception instead will cause the test to report error and you will see what's wrong instantly.

Java: custom-exception-error

$ javac TestExceptions.java
TestExceptions.java:11: cannot find symbol
symbol : class test
location: class TestExceptions
throw new TestExceptions.test("If you see me, exceptions work!");
^
1 error
Code
import java.util.*;
import java.io.*;
public class TestExceptions {
static void test(String message) throws java.lang.Error{
System.out.println(message);
}
public static void main(String[] args){
try {
// Why does it not access TestExceptions.test-method in the class?
throw new TestExceptions.test("If you see me, exceptions work!");
}catch(java.lang.Error a){
System.out.println("Working Status: " + a.getMessage() );
}
}
}
TestExceptions.test returns type void, so you cannot throw it. For this to work, it needs to return an object of a type that extends Throwable.
One example might be:
static Exception test(String message) {
return new Exception(message);
}
However, this isn't very clean. A better pattern would be to define a TestException class that extends Exception or RuntimeException or Throwable, and then just throw that.
class TestException extends Exception {
public TestException(String message) {
super(message);
}
}
// somewhere else
public static void main(String[] args) throws TestException{
try {
throw new TestException("If you see me, exceptions work!");
}catch(Exception a){
System.out.println("Working Status: " + a.getMessage() );
}
}
(Also note that all classes in package java.lang can be referenced by their class name rather than their fully-qualified name. That is, you don't need to write java.lang.)
Working Code
Try this:
public class TestExceptions extends Exception {
public TestExceptions( String s ) {
super(s);
}
public static void main(String[] args) throws TestExceptions{
try {
throw new TestExceptions("If you see me, exceptions work!");
}
catch( Exception a ) {
System.out.println("Working Status: " + a.getMessage() );
}
}
}
Problems
There are a number of issues with the code you posted, including:
Catching Error instead of Exception
Using a static method to construct the exception
Not extending Exception for your exception
Not calling the superclass constructor of Exception with the message
The posted code resolves those issues and displays what you were expecting.

Categories