Junit parallel tests logs is messed up with each other - junit

I have some test classes and methods which running parallel.
I'm using log4j2 for logging, however the log outputs to the console is messed up with each other.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
#Execution(ExecutionMode.CONCURRENT)
public class TestClass1 {
Logger log = LogManager.getLogger();
#Test
public void test1() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("Performing test1 method in " + this.getClass().getName());
}
#Test
public void test2() {
log.info("Performing test2 method in " + this.getClass().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The expected to see output in test1 TestClass1 - Performing test1 method in TestClass1
and in tests2 TestClass1 - Performing test2 method in TestClass1
Current state: Both outputs printed in first or second test together or only one tests printed.

It's look like still existing issue on IntelliJ IDEA
IntelliJ test runner mixes output from different tests when TestNG parallel is used

Regarding to opened bug in JetBrains the issue will not be fixed someday.
I tried to use TestReporter injection mentioned in bug below, however it also doesn't work.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestReporter;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
#Execution(ExecutionMode.CONCURRENT)
public class TestClass1 {
#Test
public void test1(TestReporter testReporter) {
testReporter.publishEntry("test1 started");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Test
public void test2(TestReporter testReporter1) {
testReporter1.publishEntry("test2 started");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Related

Add more context to Exception or Error in Groovy

When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.

How do I run each of my Junit 5 test as Privileged action?

I am writing integration tests using Junit 5.
I should run each test with privileged action (as logged in user).
I could achieve it by calling using Subject.doAs from each test like this:
Subject.doAs(systemSubject, (PrivilegedAction<Object>) () -> actualMethodToBeTested();
But is there any way to achieve this by using Extension in Junit 5? The reason is to avoid calling the Subject.doAs in each method.
In Junit 4, I could achieve it with the use of test decorators and runners.
Simplified version of my Junit 4 runner:
#Override
public void run(RunNotifier notifier) {
try {
Object testObject = testClass.newInstance();
for (Method method : testClass.getMethods()) {
if (method.isAnnotationPresent(Test.class)) {
notifier.fireTestStarted(Description
.createTestDescription(testClass, method.getName()));
final Subject systemSubject = getSystemSubject();
Subject.doAs(systemSubject, (PrivilegedAction<Object>)
() -> {
try {
return method.invoke(testObject);
} catch (IllegalAccessException e) {
return null;
} catch (InvocationTargetException e) {
return null;
}
});
notifier.fireTestFinished(Description
.createTestDescription(testClass, method.getName()));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

junit for multi threaded class with mockito

Please, help me write a JUnit test for this code using Mockito.
class A{
private BlockingQueue<Runnable> jobQueue;
public void methodA(List<String> messages) {
try {
jobQueue.put(() -> methodB(message));
} catch(InterruptedException e) {}
}
private void methodB(Message message) {
//other logic
}
}
Your example lacks context as to what it is methodB is doing... Without knowing what the functionality is that you want to verify, just verifying that methodB gets called wouldn't be a particularly useful test, nor is mocking the BlockingQueue. I'm going to go out on a limb and assume that methodB interacts with another object, and it's this interaction that you really want to verify, if that's the case my code and test would look something like:
class A {
private BlockingQueue<Runnable> jobQueue;
private B b;
public void methodA(Message message) {
try {
jobQueue.put(() -> methodB(message));
} catch (InterruptedException e) {
}
}
private void methodB(Message message) {
b.sendMethod(message);
}
}
class B {
public void sendMethod(Message message) {
// other logic
}
}
And my test would potentially look something like:
class Atest {
private A testSubject;
#Mock
private B b;
#Test
public void testASendsMessage() {
Message message = new Message("HELLO WORLD");
testSubject.methodA(message);
verify(b, timeout(100)).sendMethod(message);
}
#Before
public void setup() throws Exception {
testSubject = new A();
}
}
In general you want to avoid needing to verifying bits with multiple threads in a unit test, save tests with multiple running threads mainly for integration tests but where it is necessary look at Mockito.timeout(), see example above for how to use. Hopefully this helps?

unreported exception IOException; must be caught or declared to be thrown

I have a question , why does java keeps throwing that exception ! Is the problem with the stream ? because I handeled all IOExceptionS !
[[jio0yh.java:12: error: unreported exception IOException; must be
caught or declared to be thrown]]>>
That's the exception that I'm getting!
here is my code
import java.io.*;
public class jio0yh{
public static void main(String[]args){
FileInputStream OD=null;
try{
File f=new File("Binary.dat");
OD= new FileInputStream(f);
byte[]b=new byte[(int)f.length()];
OD.read(b);
for(int i=0;i<b.length;i++)
System.out.println(b[i]);
} catch(FileNotFoundException e){
System.out.println(e.getMessage());
} catch(IOException e){
System.out.println(e.getMessage());
OD.close();
}
}
}
The OD.close(); in your IOException catch block is also susceptible to throwing another IOException.
You should surround the final OD.close() in a finally block:
// ... Any previous try catch code
} finally {
if (OD != null) {
try {
OD.close();
} catch (IOException e) {
// ignore ... any significant errors should already have been
// reported via an IOException from the final flush.
}
}
}
Refer to the following for a more thorough explanation:
Java try/catch/finally best practices while acquiring/closing resources

Catch and Re-throw Exceptions from JUnit Tests

I am looking for a way to catch all exceptions thrown by JUnit tests then re-throw them; to add more detail to the error message about the test state when the exception occurred.
JUnit catches errors thrown in org.junit.runners.ParentRunner
protected final void runLeaf(Statement statement, Description description,
RunNotifier notifier) {
EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
eachNotifier.fireTestStarted();
try {
statement.evaluate();
} catch (AssumptionViolatedException e) {
eachNotifier.addFailedAssumption(e);
} catch (Throwable e) {
eachNotifier.addFailure(e);
} finally {
eachNotifier.fireTestFinished();
}
}
This method is unfortunately is final so it cannot be overridden. Also as exceptions are being caught something like Thread.UncaughtExceptionHandler will not help. The only other solution I can think of is try/catch block around each test but that solution is not very maintainable. Could anyone point me to a better solution?
You could create a TestRule for this.
public class BetterException implements TestRule {
public Statement apply(final Statement base, Description description) {
return new Statement() {
public void evaluate() {
try {
base.evaluate();
} catch(Throwable t) {
throw new YourException("more info", t);
}
}
};
}
}
public class YourTest {
#Rule
public final TestRule betterException = new BetterException();
#Test
public void test() {
throw new RuntimeException();
}
}