How to check TestNG Assert.assertEqual() conditional checking - java

Let me explain what I exactly expecting
I have a method like the following
public void removeByObject()
{
try {
DsrCollection dsrCollection = new DsrCollection();
dsrCollection. setNuId(180);
dsrCollectionRepository.remove(dsrCollection);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Here I want to check that the particular method removeByObject() executed successfully or not(also want to involve Assert.assertEqual(dsrCollectionRepository.remove(dsrCollection),??)). So for checking the condition what should be the actual value.
Or in a more specific way what object should appear in actual value place. My requirement is like if application failed to execute dsrCollectionRepository.remove(dsrCollection) it should return the assertError message

To make removeByObject() more testable you can simply extract the code in the try block into its own method. e.g.:
public class DsrCollectionRepositoryManager /* Or whatever your class is called. */ {
/* ... */
public void removeByObject() {
try {
removeByObjectOrThrow();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
protected boolean /* or whatever your return type is */ removeByObjectOrThrow() {
DsrCollection dsrCollection = new DsrCollection();
dsrCollection.setNuId(180);
return dsrCollectionRepository.remove(dsrCollection);
}
/* ... */
}
Now you can test removeByObjectOrThrow() and see if it throws an exception or not.
If you are trying to test it where removeByObject() is called on your behalf and/or you don't want to call removeByObjectOrThrow() directly then you can subclass your unit under test. e.g.:
public class DsrCollectionRepositoryManagerTest {
#Test
public void removeObjectSuccessful() {
boolean expected = true;
DsrCollectionRepositoryManager dsrCollectionRepositoryManager = new DsrCollectionRepositoryManager() {
#Override
protected boolean removeByObjectOrThrow() {
try {
boolean actual = super.removeByObjectOrThrow();
Assert.assertEquals(actual, expected);
return actual;
} catch (Exception cause) {
String message = "`removeObject` should not have thrown an exception but did";
throw new AssertionError(message, cause);
}
}
};
dsrCollectionRepositoryManager.removeByObject();
}
#Test
public void removeObjectUnsuccessful() {
DsrCollectionRepositoryManager dsrCollectionRepositoryManager = new DsrCollectionRepositoryManager() {
#Override
protected boolean removeByObjectOrThrow() {
super.removeByObjectOrThrow();
String detailMessage = "`removeByObject` should have thrown an exception but did not";
throw new AssertionError(detailMessage);
}
};
dsrCollectionRepositoryManager.removeByObject();
}
}
As I don't know the name of your unit under test nor the type of what you want to use assertEquals with I've made things up but the idea is the same: isolate the code you want to test and test it.

Does dsrCollectionRepository.remove(obj) return a value indicating whether the removal is successful or not? I'd recommend implementing the function so it does return a boolean on a successful removal of an object, otherwise you rely on exceptions to inform you of the failure of the function.
If it already returns a boolean value just assertTrue(dsrCollectionRepository.remove(dsrCollection);
If the failure of the function throws a known exception you can use the following annotation to test the function:
#Test(expectedExceptions = MyException.class), however you then rely on the fact that only that exception can be thrown while performing that function, which is problematic if someone adds an exception that can be thrown in implementation without your knowledge.

Related

How to handle while throwing multiple custom exception

From a single method trowing two different custom exceptions based on the condition. While creating a custom exception passing two things one is an error message and another one is error code as a string. But I'm unable to get the error based on the error code. getting an error while calling processErrorCodes() method. Could anyone please help me in fixing this.
// BackgroundException is a custom EXCEPTION
public class BackgroundException extends Exception {
private static final long serialVersionUID = 4664456874499611218L;
private String errorCode="Unknown_Exception";
public BackgroundException(String message, String errorCode){
super(message);
this.errorCode=errorCode;
}
public String getErrorCode(){
return this.errorCode;
}
}
// Similarly I have InvalidException custom exception
public class MyExceptionTest {
public void methodTest(){
String policyId =null;
String policyNotification = null;
String policyStatus = null;
try {
if(policyNotification !=null) {
if(policyStatus!=null) {
if(policyId!=null) {
}
else{
throw new InvalidException("Policy ID Is Null","POLICY_ID");
}
}else{
throw new BackgroundException("Policy Status Is Null","POLICY_STATUS");
}
}
else{
throw new BackgroundException("Policy Notification Is Null","POLICY_NOTIFICATION");
}
} catch (BackgroundException | InvalidException e ) {
// TODO Auto-generated catch block
try {
processErrorCodes(e);
} catch (MyExcep e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.getMessage();
}
}
private static void processErrorCodes(Exception e) throws BackgroundException,InvalidException {
switch(e.getErrorCode()){
case "POLICY_NOTIFICATION":
System.out.println(e.getMessage());
throw e;
case "POLICY_ID":
System.out.println(e.getMessage());
throw e;
case "POLICY_STATUS":
System.out.println(e.getMessage());
throw e;
default:
System.out.println("Unknown exception occured, lets log it for further debugging."+e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
MyExceptionTest mt = new MyExceptionTest();
mt.methodTest();
}
}
I just want to handle those exceptions based on the error code.
You need a common superclass for all your custom exceptions, let say MessageCodeException, extending Exception and the accept this super class type as a parameter inside of your processErrorCodes method
public abstract class MessageCodeException extends Exception {
public abstract String getCode();
// you can have a same abstract method for message
}
public class BackgroundException extends MessageCodeException {
// ...
}
public class InvalidException extends MessageCodeException {
// ...
}
//and now the process method will look like
private static void processErrorCodes(Exception e) throws ... {
// ...
}
That's abvious that for current implementation you cannot access code field, because Exception class interface does not provide anything like this
BTW it seems to be very bad idea to create Exception driven business validation logic. Wouldn't it be better to create some kind of ValidationResult object with list (lists) of errors/warning/successes and to process such validation result at the end? The purpose of the Exception existence is not to control application flow, but to force user to provide some support for critical situations (or to handle somehow unexpected situations with RuntimeException)

How to avoid repeating complex exception handling code in a wrapper class?

I have this class that wraps an object:
public class MyWrapper implements MyInterface {
private MyInterface wrappedObj;
public MyWrapper(MyInterface obj) {
this.wrappedObj = obj;
}
#Override
public String ping(String s) {
return wrappedObj.ping(s);
}
#Override
public String doSomething(int i, String s) {
return wrappedObj.doSomething(i, s);
}
// many more methods ...
}
Now I want to add complex exception handling around the wrappedObj call.
It is the same for all the methods.
How do I avoid repeating the same exception handling code over and over?
If your exception handling is fully generic you could implement the wrapper as InvocationHandler:
public class ExceptionHandler implements java.lang.reflect.InvocationHandler {
public ExceptionHandler(Object impl) {
impl_ = impl;
}
#Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(impl_, args);
}
catch (Exception e) {
// do exception handling magic and return something useful
return ...;
}
}
private Object impl_;
}
and then wrap it around an instance as follows:
MyInterface instance = ...
MyInterface wrapper = (MyInterface)java.lang.reflect.Proxy.newProxyInstance(
instance.getClass().getClassLoader(),
new Class[] { MyInterface.class },
new ExceptionHandler(instance));
wrapper.ping("hello");
If you want to avoid the cost of reflection, than just use a router function.
#Override
public String ping(String s) {
return (String) call("ping");
}
private Object call(String func) {
try {
switch(func) {
case "ping": return wrappedObj.ping(s);
// ... rest of functions ... //
}
} catch(Exception e) {
log(e);
}
}
The compiler can than effectively just jump to the function without pulling up Object specs or handlers. (A smart enough compiler may even just compile this to identical execution code as your current code, especially if you can cut the cast by always returning the same kind of object)
If you don't care about the thread and just want a default exception handler...
For the whole Java Runtime, call Thread.setDefaultUncaughtExceptionHandler
For a ThreadGroup, override ThreadGroup.uncaughtException
For a single Thread, call Thread.setUncaughtExceptionHandler
The advantage to a default handler, is that you can then add specific error handlers where needed, but the down side is you do lose the executing thread on error.

Skip test when exception occurs [duplicate]

My application have several execution modes, and in 1 mode it is normal that some of my tests will throw a concrete exception. I need to annotate this methods with something like #SkipOnFail that will set method as skipped if exception was thrown.
thanks in advance!
#Edit(for my question to be more clear)
#Test(expected=ConcreteException.class)
does not work for me because i need my tests to pass even if ConcreteException.class was not thrown(expected tag in junit will mark my test as failed if this exception won't be thrown), and to be skipped otherwise. In all other cases it should work as always.
#Solution that worked for me(junit v4.7) thx to #axtavt
#Rule
public MethodRule skipRule = new MethodRule() {
public Statement apply(final Statement base, FrameworkMethod method, Object target) {
if(method.getAnnotation(SkipOnFail.class) == null) return base;
return new Statement() {
#Override
public void evaluate() throws Throwable {
try{
base.evaluate();
} catch (ConcreteException e) {
Assume.assumeTrue(false);
}
}
};
}
};
#Thx
I don't think that such a feature is available out of the box, but it should be pretty easy to implement with custom TestRule and Assume, something like this:
#Rule
public TestRule skipRule = new TestRule() {
public Statement apply(final Statement base, Description desc) {
if (desc.getAnnotation(SkipOnFail.class) == null) return base;
return new Statement() {
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (MyExceptoion ex) {
Assume.assumeTrue(false);
}
}
};
}
};
What about using JUnit Extensions?
The following example is taken from their Tutorial.
It provides aditional annotations for Prerequisites (#Prerequisite): Ignore tests based on conditions.
The required approach would be to check this during running tests. So you can simply add a #Prerequisite(requires="") annotation.
public class TestFillDatabase {
#Prerequisite(requires = "databaseIsAvailable")
#Test public void fillData() {
// ...
}
public boolean databaseIsAvailable() {
boolean isAvailable = ...;
return isAvailable;
}
}
public class TestFillDatabase {
#Prerequisite(requires = "databaseIsAvailable")
#Test public void fillData() {
// ...
}
public boolean databaseIsAvailable() {
boolean isAvailable = ...;
return isAvailable ;
}
}
This specified methods with #Prerequisite(requires = "databaseIsAvailable") must be a public method, returning a boolean or Boolean value.
If these methods will be consolidated in helper classes, you can also specify static methods within a class to be called using #Prerequisite(requires = "databaseIsAvailable", callee="DBHelper").
public class TestFillDatabase {
#Prerequisite(requires = "databaseIsAvailable", callee="DBHelper")
#Test public void fillData() {
// ...
}
}
public class DBHelper {
public static boolean databaseIsAvailable() {
boolean isAvailable = ...;
return isAvailable ;
}
}
Also using the Assume class (since jUnit 4.4), you can use assumeNoException():
try{
base.evaluate();
} catch (ConcreteException e) {
Assume.assumeNoException("Concrete exception: skipping test", e);
}
I searched for the docs about JUnit and it appears that from version 4.9 they have introduced what they call test rules (see TestRule). You may start from this.
The ExpectedException class marked as #Rule could be of some help in order to check for exceptions thrown but not mandatory for the test to pass.
For more advanced usage I cannot say for the moment as I've just discovered it.

How to get the message from an Exception from outside the method that generates it?

I have write my Java code with the proper try{ } catch{ } blocks for dealing with exceptions, but once the error occurs and the typical message is shown (e.g, through the console), how could I get the Exception message, Stack trace, or similar text pieces from outside that method for further processing it to elaborate a model on how to react to them?
I'm working with multiagent systems and a way of dealing with errors for the agents would be to text-process that kind of messages (Exceptions, etc) to decide about how to behave. But how to access that text if the generating method is returning, let's say, an Integer[]?
When using your try{} catch{} statement, the error message shown to the console is shown because of the (i'm guessing) autogenerated method stub such as
try{
}catch(Exception e){
//TODO autogenerated method stub
e.printStackTrace();
}
the call to "e.printStackTrace()" is what is actually printing to the console.
Instead of having this print to the console, you could instead store this in a variable and perform analysis on it.
You shouldn't be using exceptions for application logic. If you want to have agents respond to messages, implement a message-queue system. Each agent will have its own message queue that it will inspect to see what messages it has. When messages are processed depends on your agent's lifecycle.
To send messages, you could directly add it to the recipient's message-queue, but a better solution would be to have a dispatcher that accepts a Message object that contains the recipient and the message, and then it figures out the correct agent that should receive the message.
You don't have to use a messaging library; you should be able to write a simple one yourself using Queue<E>. Be aware of potential concurrency issues if your agents are all running in their own threads.
You could always pervert the use of Exceptions and use something like this:
import java.util.function.Consumer;
public class ExceptionalOptional<T> {
#FunctionalInterface
interface RunnableWithException<T> {
public T call() throws Exception;
}
private final T value;
private final Exception exception;
public ExceptionalOptional(T value) {
this.value = value;
this.exception = null;
}
public ExceptionalOptional(Exception exception) {
this.value = null;
this.exception = exception;
}
public static <T> ExceptionalOptional<T> from(T value) {
return new ExceptionalOptional<T>(value);
}
public static <T> ExceptionalOptional<T> from(Exception e) {
return new ExceptionalOptional<T>(e);
}
public static <T> ExceptionalOptional<T> wrap(
RunnableWithException<T> runnable) {
try {
return from(runnable.call());
} catch (Exception e) {
return from(e);
}
}
public boolean hasValue() {
return exception == null;
}
public boolean hasThrown() {
return exception != null;
}
public T getValue() {
return value;
}
public Exception getException() {
return exception;
}
public ExceptionalOptional<T> withValue(Consumer<T> consumer) {
if (hasValue()) {
consumer.accept(value);
}
return this;
}
public ExceptionalOptional<T> onException(Consumer<Exception> consumer) {
if (hasThrown()) {
consumer.accept(exception);
}
return this;
}
public <E extends Exception> ExceptionalOptional<T> onException(
Consumer<E> consumer, Class<E> klass) {
if (hasThrown() && klass.isInstance(exception)) {
consumer.accept(klass.cast(exception));
}
return this;
}
}
This allow you to handle your use case in a fluent matter starting off like this:
ExceptionalOptional<FileInputStream> fis =
wrap(() -> new FileInputStream(new File("test.txt")));
I still think what you want to do is an XY problem.

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.

Categories