How to have 100% test coverage for function that calls invokeLater()? - swing

I am using Junit4.
This is my test class:
import org.junit.Test;
public class UIUtilTest {
#Test
public void testMultiline() {
var multiLineText = "one\ntwo";
UIUtil.showError(multiLineText, "title");
assert true;
}
}
I have the following Jacoco coverage result:
How can I test the lambda that Jacoco is complaining about in order to hit 100% coverage?

Make test wait for dialog to pop. Having your implementation you can simply add another task to the EDT queue and wait for it to finish.
#Test
public void testMultiline() throws InterruptedException, InvocationTargetException {
String multiLineText = "one\ntwo";
UIUtil.showError(multiLineText, "title");
SwingUtilities.invokeAndWait(() -> {
//just wait, nothing more
});
assert true;
}

Related

How to write Junit test case for start method of consumer Verticle in vert.x?

I have implemented one Verticle as mentioned below. Verticle is working as expected. Now I am trying to write Junit test case for this Verticle which could test the start method, the handler method handleRequest(), and the method getSomeData() inside handler which returns Future. Either single test case to test all three method or individual test case to test individual method should be fine.
I know writing Junit test cases for synchronous code but have no idea how exactly to write Junit TCs for Verticle in vert.x which is asynchronous. Could anyone please guide me here? I also have router verticle from which I am sending message to this consumer verticle MyVerticle but I am thinking to write Jnuit test cases for this consumer verticle first. Please help.
#Component
public class MyVerticle extends AbstractVerticle{
#Override
public void start() throws Exception {
super.start();
vertx.eventBus().<String>consumer("address.xyz").handler(handleRequest());
}
private Handler<Message<String>> handleRequest() {
return msg -> {
getSomeData(msg.body().toString())
.setHandler(ar -> {
if(ar.succeeded()){
msg.reply(ar.result());
}else{
msg.reply(ar.cause().getMessage());
}
});
};
}
private Future<String> getSomeData(String inputJson) {
Promise<String> promise = Promise.promise();
promise.complete("Returning Data");
return promise.future();
}
}
I recommend using the vertx-unit project, wich makes it easy to test async code. For your parcular case it would go like this:
import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(VertxUnitRunner.class)
public class MainVerticleTest {
private Vertx vertx;
#Before
public void setup(TestContext ctx){
Async async = ctx.async();
this.vertx = Vertx.vertx();
vertx.deployVerticle(MyVerticle.class.getName(), h -> {
if(h.succeeded()){
async.complete();
}else{
ctx.fail();
}
});
}
#Test
public void test_consumption(TestContext ctx) {
Async async = ctx.async();
vertx.eventBus().request("address.xyz","message", h ->{
if(h.succeeded()){
ctx.assertEquals("Returning Data",h.result().body().toString());
async.complete();
}else{
ctx.fail(h.cause());
}
});
}
}

Override Mockito statements in local function doesn't work with PER CLASS mode?

I'm new to JUnit5 and I noticed something weird happening.
Let's see it with an example,
I have a source class named A
class A {
someDownStreamService service;
void printer() {
int getData = service.getIntegerData();
print(getData);
}
}
Now when I wrote test case,
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
class JUnit5TestCaseForClassA {
#Mock
private someDownStreamService service;
#InjectMocks
private A a;
#BeforeEach
setUp() {
initMocks(this);
Mockito.when(service.getIntegerData()).thenReturn(25);
}
#Test
void test1() {
a.printer();
}
#Test
void test2() {
Mockito.when(service.getIntegerData()).thenReturn(19);
a.printer();
}
}
When I trigger test2() individually, the printer() function is printing 19 as I suppose Mockito.when() statement is overridden to return 19 in test2() function over what was registered in #BeforeEach to return 25.
And when I execute all the test classes under class 'JUnit5TestCaseForClassA', I see that printer() function is printing 25 for both these test function's. Is the overriding not happening? Or what is the issue?
Why is this discrepancy?????
I can see making #TestInstance(TestInstance.Lifecycle.METHOD), will resolve the issue, as each testcases are triggered with new test instance. But I want to test with Lifecycle.PER_CLASS.
I have slightly modified your example to make it testable (with assertions) as follows.
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.mockito.InjectMocks;
import org.mockito.Mock;
#TestInstance(Lifecycle.PER_CLASS)
public class MockitoJUnitJupiterTestCase {
#Mock
MyService service;
#InjectMocks
A a;
#BeforeEach
void setUp() {
initMocks(this);
when(service.getData()).thenReturn(25);
}
#Test
void test1() {
assertEquals("data: 25", a.printer());
}
#Test
void test2() {
when(service.getData()).thenReturn(19);
assertEquals("data: 19", a.printer());
}
}
interface MyService {
int getData();
}
class A {
MyService service;
String printer() {
return "data: " + service.getData();
}
}
When I execute that using Mockito 2.23.4 or 2.28.2 and JUnit Jupiter 5.5 snapshots, the tests pass.
Can you try out this variation of your tests and let us know if both tests pass when executing the entire test class?

JUNIT test case for void method

I have a method whose JUnit test case I have to write. It just calls the main processing method of the project and does nothing else. Also, the main processing method also has return type as void.
How shall I test such a "method1"?
public void method1() {
obj1.mainProcessingMethod():
}
Given a class:
public class A {
private Obj obj1;
public void method1() {
obj1.mainProcessingMethod();
}
public void setObj1(Obj obj1) {
this.obj1 = obj1;
}
}
In test for this class, the only thing to test would be verification whether method obj1.mainProcessingMethod() was invoked exactly once.
You can achieve this with Mockito.
import org.junit.Test;
import org.mockito.Mockito;
public class ATest {
private Obj obj1 = Mockito.mock(Obj.class);
private A a = new A();
#Test
public void testMethod1() {
a.setObj1(obj1);
a.method1();
Mockito.verify(obj1).mainProcessingMethod();
}
}
Here you create a mock object for class Obj, inject it into instance of A, and later use mock object to check which method invocations it recorded.
Inside the test you need to verify that the method mainProcessingMethod(): is called on the object obj1.
you can use something like
Mockito.verify(yourMockObject);

JavaFX application thread exits during JUnit test

I'm testing a JavaFX application with JUnit, In most cases I use the #Rule approach from Basic JUnit test for JavaFX 8. However there are a couple of situations where this approach does not work, so I setup the JavaFX platform manually, and call Platform.runLater() where necessary.
What appears to be happening is that at some point the JavaFX application thread is disappearing, this means subsequent tests lockup as the Platform.runLater() calls never return - that's why I've added timeouts in example. I've proved this with calls to Thread.getAllStackTraces()
Yes I'm aware of JemmyFX, and I'll likely move to it soon, but I'd still like to understand what's going on here...
Code
public class JavaFxThreadJUnit {
private static boolean setup;
private Stage stage;
#Before
public void before() throws Exception {
setupJavaFX();
Platform.setImplicitExit(true);
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage = new Stage();
stage.show();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
#After
public void after() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
stage.hide();
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
#Test
public void foo() throws Exception {
// test stuff...
System.out.println("foo test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
#Test
public void bar() throws Exception {
// test stuff...
System.out.println("bar test: "
+ Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
}
// https://gist.github.com/andytill/3835914
public static void setupJavaFX() throws InterruptedException {
if (setup) {
return;
}
long timeMillis = System.currentTimeMillis();
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// initializes JavaFX environment
new JFXPanel();
latch.countDown();
}
});
System.out.println("javafx initialising...");
latch.await();
System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
setup = true;
}
}
Output... JavaFX Application Thread was there, then it's gone...
javafx initialising...
javafx is initialised in 327ms
bar test: [Thread-3, ReaderThread, AWT-Shutdown, AWT-Windows, Thread-2, Finalizer, JavaFX Application Thread, Signal Dispatcher, Java2D Disposer, AWT-EventQueue-0, main, Attach Listener, Reference Handler, QuantumRenderer-0]
foo test: [Thread-3, ReaderThread, Java2D Disposer, AWT-Windows, Thread-2, main, Finalizer, Attach Listener, Reference Handler, Signal Dispatcher]
Looks like the stage closing is triggering an "implicit exit". I'd still be interested to know why this doesn't also affect tests using the #Rule approach...
Workaround:
Platform.setImplicitExit(false)

How to run something after all the #Before's have happened?

We're using #Before's all along the hierarchy to get some test data inserted into the database before tests execute. I want to commit all that data to the database just before the #Test starts running.
One way to do this would be to commit the data as the last step in this test class' #Before method. But we have hundreds of such classes, and don't want to go in and modify all of those.
I've played with ExternalResource #Rule and TestWatcher #Rule...but they don't afford a way to hook in after all the #Before's have happened.
I'm thinking I need to look at building a custom TestRunner to do this.
Is that the right track?
What you are looking for, seems inconsistent to me. Settind some data and committing them are very close operations and shouldn't belong to different places. On the contrary, I would rather put them into one function and call it with actual parameters set to values you want to insert. Or use SQL strings as actual parameters. And call this finction from #Before
If you are insisting, there is no problem to do it. Create descendant classes for your Junit classes:
package ...;
import org.junit.Before;
public class NewAndBetterYourTest1 extends YourTest1 {
#Override
#Before
public void setUp() {
super.setUp(); // this is where you are setting everything.
makeCommits();
}
}
Only don't forget to launch these new tests
While you can't do quite what you are asking without a custom Runner, you could ensure that all of the data created in the #Before methods is committed with a Rule:
public class LocalDatabase extends ExternalResource {
private DataSource dataSource;
#Override
protected void before() {
dataSource = createLocalDatabase();
}
#Override
protected void after() {
try {
destoyLocalDatabase(dataSource);
} finally {
dataSource = null;
}
}
public void run(Callback callback) {
if (dataSource == null) {
throw new IllegalStateException("No DataSource");
}
Collection con = null;
try {
con = ds.getConnection(DB_USERNAME, PASSWORD);
callback.execute(con);
con.commit();
} finally {
if (con != null) con.close();
}
}
You can have this as a Rule in your base class:
public DatabaseTest {
#Rule
public LocalDatabase final localDatabase = new LocalDatabase();
}
And could could use it in a #Before method in any subclass
public UserDaoTest extends DatabaseTest {
#Before
public void populateInitialData() {
localDatabase.run(new Callback() {
#Override
public void execute(Connection con) {
...
}
});
}
...
}