How should I unit test the main method of a JavaFX program? - java

Right now, I'm considering incorporating 100% code coverage into my project. However, I'm having trouble unit testing the main entry point of my code:
public static void main(String[] args) {
launch(args);
}
This method is difficult to test because it launches an entirely new JavaFX program in the background. In addition to this behavior, a JavaFX program cannot be started more than once. Moreover, the documentation for javafx.application.Application explictly states that, "A JavaFX Application should not attempt to use JavaFX after the FX toolkit has terminated or from a ShutdownHook, that is, after the stop() method returns or System.exit(int) is called."
I am encountering this project because I'm also working with TestFX, a library that helps with clean testing for JavaFX. However, this library does not offer support for the testing of the main method, and as a result I have to write a workaround. There is a possibility of the developers of TestFX knowing about a possible workaround for this problem, for each and every unit tested method, a new instance of an Application is started. Perhaps there could be a way to completely shutdown and reset all variables of a JavaFX program.
To be fair, this method is not that significant to test, however it would be pleasant to have 100% code coverage. It would be entirely reasonable to not test this method as well. The full class can be found below:
package com.meti.app;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* #author SirMathhman
* #version 0.0.0
* #since 4/5/2019
*/ //Main MUST remain public in order for JavaFX Application to start.
public class Main extends Application {
static InfinityImpl implementation = new Infinity();
static Main instance;
#Override
public void start(Stage primaryStage) {
instance = this;
implementation.start(primaryStage);
}
#Override
public void stop() {
implementation.stop();
instance = null;
}
public static void main(String[] args) {
launch(args);
}
}
The static variables above are irrelevant to the aforementioned question and are used for testing purposes in another class which ensures that the delegation works correctly. The application delegates most of the operations to a delegate class which makes the code easier to test.
Moreover, IntelliJ doesn't allow methods to be excluded during code testing.
If you have any other questions, please let me know. Thank you!
Some additional reading:
How to call launch() more than once in java
https://github.com/TestFX/TestFX/blob/master/subprojects/testfx-core/src/main/java/org/testfx/api/FxToolkit.java

Related

Eclipse not having run as java applet application

I setup my eclipse for PROCESSING perfectely..
I am using Eclipse Oxygen and installed PROCESSING 3.3.6
i am trying to run processing program in eclipse and there is no option is run as Applet
My code is below :
package processing01;
import processing.core.PApplet;
public class Processing01 extends PApplet{
public static void main(String[] args) {
PApplet.main("Processing01");
}
public void settings(){
size(300,300);
}
public void setup(){
fill(120,50,240);
}
public void draw(){
ellipse(width/2,height/2,second(),second());
}
}
Processing 3 no longer supports running as an applet. From the Processing 3 change list:
Applet is gone — Java's java.awt.Applet is no longer the base class used by PApplet, so any sketches that make use of Applet-specific methods (or assume that a PApplet is a Java AWT Component object) will need to be rewritten.
The PApplet class no longer extends the Applet class, which means you can't treat Processing sketches as a component anymore, and you can't run them as an applet. You can only run them as an application.
Applets are dead, and shouldn't be used anyway.
Because having package the code would be
//replace
PApplet.main("Processing01");
//with
PApplet.main("processing01.Processing01");

JavaFX Application class - difference between default constructor and init method

I have written a little test application that looks like this:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
public class Test extends Application {
public Test() {
System.out.println("first");
}
#Override
public void init() throws Exception {
System.out.println("second");
super.init();
}
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println("third");
Platform.exit();
}
#Override
public void stop() throws Exception {
System.out.println("fourth");
super.stop();
}
public static void main(String[] args) {
launch(args);
}
}
The output is:
first
second
third
fourth
Now, I am asking myself where the difference is between using the default constructor or the init method for initialising some required things.
Thanks!
P.S.: This question is not duplicate with this one, because my issue does not handle the initialisation of variables. My question is JavaFX specific!
When the Application is launched, the following steps are executed during the launch process:
The instance of the Application subclass that should be launched is created. (Constructor is called)
The init() of that instance is called.
The start method of that instance is called.
See javadoc for Application
Since you exit the application after the start method is called, the stop method of the instance is called.
Note that there is no need to use super.init() and super.stop():
From the javadoc
The init and stop methods have concrete implementations that do nothing.
The differences of constructor, init and start are:
Constructor
If your application is not final the application class could be extended. Since the constructor of the extending class is not complete, it may be dangerous to pass a reference to the class to other classes in this state. Also the instance hasn't been initialized to a point where the getParameters method returns the parameters.
init
Initialisation should generally be done in this method. This method isn't run from the fx application thread, so some things cannot be done from this method, like creating a Stage.
start
Last step in the initialisation. Do things that require to be run from the application thread here. Be careful not to block this thread with long-runing operations however, since this freezes the GUI.
Application Class having init() method which you have override.
The Init method will call immediately after the Test class construction.
Init method is actually an internal method of Application Class. This method is actually initialize the whole FX application components internally.
Application class JavaDoc
it may construct other JavaFX objects in this method.

how to print "hello world" without MAIN method and also without using STATIC and FINAL key word in java

class a {
public static void main(String args[]) {
}
}
i want to print "hello world" without touch or use above code and also without use of static and final keyword......
What are the different ways to initiate code execution.
Use public static void main(String args[]) { ... }
Use your static class initializer static { ... }. Problem: You need to get the class to load first. Solution: attempt to start the main method, but that means you need to have at least an empty main. However - OP states we cannot use 'static'.
Use an instance initializer { ... }. Problem: How do you instantiate an instance. Solution: initialize a static field with a class instance. However - OP states we cannot use static fields.
So what is left. I assume that we can use the empty main posted by the OP. From there on we build up a 4th solution:
public enum Play {
PLAY;
{ System.out.println("Hello World!"); }
public static void main(String args[]) { }
}
This should fulfill the conditions:
we do not modify the static main method, although we need the empty body just to get the class loaded.
we do not use a static initializer, we use an instance initializer instead.
to instantiate, and get the instance initializer started, we use an enum. Enum's start the initializer for each instance, meaning for each of the enum constants.
Also note the output when you try to execute a class without a main:
$ java -classpath . Play
Error: Main method not found in class Play, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
So that leaves us also the clue that we potentially can use javafx.application.Application. I did not investigate this trail any further.
You can create a JavaFX application, which is usually for displaying a GUI, and use it to output hello, world to the console and immediately shut the JavaFX GUI system down. JavaFX applications are executed by a special launch path in the java launcher. JavaFX applications do not need a main, static and final keywords.
The following snippet is just for demo purposes, I wouldn't recommend writing a JavaFX application unless you actually wish to display a GUI.
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
public class PlayApp extends Application {
#Override
public void start(Stage stage) {
System.out.println("hello, world");
Platform.exit();
}
}
// Totally useless code from the original question
// goes below the real app code and is just ignored
// and never used when the application runs.
class a {
public static void main(String args[]) {
}
}
You need to use Oracle Java 8+ to compile and execute the JavaFX application as below:
javac PlayApp.java
java PlayApp
The a class is in the PlayApp.java file only to meet the original poster's requirement from a comment:
it means the above code is fixed, you can't modify the above code but yes u can write anything to print "hello world" above or belove this code
Really, if you are writing a console application, just use a standard app format (with a static main method) instead:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
Unrelated advice on asking questions
In future, if you post such questions, I suggest that you also supply the reason for the question and why the bizarre constraints are placed on solutions. Also, address concerns such as WorldEnder's first comment on your question: "is this a code challenge? If not.. why?"
You can't just print "hello world" without MAIN method and also without using STATIC and FINAL key word in java because the main method is a function required you don't have to apply any rocket science in that thing if u are using intelliJ IDEA or any other IDE anyways this is the code
public class Basics_Of_Java {
public static void main(String[] args) {
System.out.println("Hello world");
basics of java in 1st line is the name of the java file you may have another name.

Getting application instance in javafx

How can I get the application instance when using javafx?
Normally you launch an application this way:
public class LoginForm {
public static void main(String[] args) {
LoginApplication.launch(LoginApplication.class, args);
}
}
The method launch does not return an instance of application.
Is there a way I could get the instance?
I was just trying to find an easy, logical way to do exactly this. I haven't. It would be really nice if there was an Application.getApplicationFor(AppClass.class) that managed some singletons for you--but no.
If we restrict the problem space it's pretty easy to solve. If we make the class a singleton, then it's cake... A simplified singleton pattern should work fine:
class MyApp extends Application
{
public static MyApp me;
public MyApp()
{
me=this;
}
...
}
me can be null if it hasn't been instantiated by the system yet. It would be possible to protect against that with more code.
... implementing code...
Just implemented this--seems to work (barring any strange threading situations)
I have a slightly different situation, I'm wedging a javaFX screen into an existing swing GUI. It works fine, but I need to ensure that Application.launch is only called once. Adding this requirement, my final solution is thus:
(Sorry but the syntax has some groovy in it, should be easy for any Java user to translate)
class MyClass extends Application{
private static MyClass instance
public MyClass() {
instance=this
}
public synchronized static getInstance() {
if(!instance) {
Thread.start {
// Have to run in a thread because launch doesn't return
Application.launch(MyClass.class)
}
while(!instance)
Thread.sleep(100)
}
return instance
...
} // class
This manages blocking until Application.launch has completed instantiating the class, getting instances from other locations and ensuring that Application.launch gets called exactly once as long as getInstance has been called at least once.

Running a non-Activity class

I have more of a understanding problem.
I added a new class in my Android porject. The class is not an Activity class, it uses objects of also non-activity classes to get some information.
However, I can not test, if it does its job. I can not debug it, none of the Log- messages that I built in the code show up in logcat.
How can I test a class in a project otherwise?
I have pretty limited knowledge in java+Android+Eclipse, so I don't know, which one is the issue here.
Please help.
Create test Activity, add there some UI elements which do some logic with your non-Activity class, and test it
Add a class with
public static void main(String[] args)
and run it.
E.g.
public class Runner {
public static void main(String[] args) {
//do smth here
}
}
You could simply develop a basic Activity with buttons that trigger the functions of your class

Categories