public class example
{
public void method()
{
System.out.println("Shouldn't be here!");
}
}
public class examplemain
{
public static void main(String[] args)
{
example obj = new example();
obj.method();
System.out.println("Inside Main");
}
}
I want to test main only and do not want to call method function.
I used this-
class examplemainTest
{
#Test
void main()
{
example obj = mock(example.class);
doNothing().when(obj).method();
String[] args = new String[0];
examplemain.main(args); //line 1
obj.method(); //line 2
}
}
But still it is calling method function in line 1 and it is only working for line 2.
Following is the output I got after running the test.
Shouldn't be here!
Inside Main
Process finished with exit code 0
The obj variable in examplemain.main() and examplemainTest.main() refer to different objects. In examplemain.main() you call method on the concrete object that you created on the previous line. In examplemainTest.main() you call the method on the mocked object you created in the beginning of the method.
You seem have trouble understanding some of the most fundamental concepts in Java programming. You should spend more time studying object initialization, object references, static access, field visibility and scope before diving into the fairly advanced topic of mocking dependencies in unit tests.
I researched a little bit, best way to handle testing of such kind of classes is provided here
Related
This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Cannot make a static reference to the non-static method
(8 answers)
Closed 5 years ago.
For some reason when I'm trying to call methods using a main method or try changing variables declared outside the main method I get forced into having to change everything to static. This is fine in places but when it comes to needing to change values later in the code for example using a Scanner for input the main method just takes it to a whole new level trying to make me change the Scanner library etc.
This example shows what happens if I try calling a method.
This example shows what happens when I try alter the value of a variable declared outside my main method.
I have never faced an issue like this before when writing java code I've tried recreating the classes/ project files etc but nothing works. I've tried looking everywhere for a solution but I can't seem to find one probably due to the fact that I don't know what to search for. I've probably made myself look like a right idiot with my title haha! Any suggestions people?? Thanks in advance!
Maisy
It can be a bit confusing to get out of "static land" once you are in your main() method. One easy way is to have another object contain your "real" (non-static) top level code and then your main method creates that object and starts it off.
public static void main() {
MyEngine engine = new MyEngine();
// core logic inside of start()
engine.start();
}
I hope that this was clear enough for you. Good luck Maisy!
When calling methods form a main you have to instantiate the class they are in, unless it's a static function
this is because that a class is a sort of template and there is nothing saved about it before it get instantiated
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
}
public method method(){}
}
in the example above i instantiated a TestClass and then called on the testClass instance
there is some functions and variables on classes you might want static, because a static on a class is shared between ALL instances, and can be called on the class, say you want to know how many instances were created then something like this can be done.
public class TestClass{
public static void main(String[] args){
TestClass testClass = new TestClass();
testClass.method();
System.out.print(TestClass.instances +""); // note that i call on
//the class and not on an instance for this static variable, and that the + ""
//is to cast the int to a string
}
public static int instances = 0; // static shared variable
public TestClass(){instances++;} // constructor
public method method(){}
}
You need to do some Object Oriented Programming tutorial and to learn some basic.
As answer for your problem to call without using static you have to create an instance of the main Class
let suppose the following class Foo
public class Foo{
private int myVarInteger;
public int getMyVarInteger(){ return this.myVarInteger;}
public void setMyVarInteger(int value){this.myVarInteger = value;}
public static void main(String[] args){
Foo myClassInstanceObject = new Foo();
// now we can access the methods
myClassInstanceObject.setMyVarInteger(5);
System.out.println("value ="+myClassInstance.getMyVarInteger());
}
}
I recently wrote a class that implements the run method and then parses a video file while grabbing meaningful information. Now I've created a new class that performs a similar operation on the same file but uses a different method of parsing while grabbing other meaningful information. Long story short, I'm required to use two different methods of parsing because some data cannot be extracted by one and some cannot be extracted by the other. The problem I'm facing is that both classes implement the run method, but now I need to start the new class, grab information, start the other class, grab information, then compare the information and print it to the console. This is the gist of what I'm trying to do:
public class first {
[public member variables]
....
public void run(String[] args) {
// parse the file from args and store data
}
public static void main(String[] args) {
new first().run(args); // <------ A
}
}
public class second {
[public member variables]
....
public void run(String[] args) {
// parse the file from args and store data
}
public static void main(String[] args) {
new second().run(args);
}
}
What I'm trying to do is call the first class's main method in order to keep a reference to the class and grab the data from it when it's finished. So I added something like this in the second class:
public class second {
[public member variables]
first firstClass;
int dataFromFirst = 0;
....
public void run(String[] args) {
// parse the file from args and store data
firstClass = new first();
firstClass.main(args); // <------ B
dataFromFirst = firstClass.getSomeData(); // <------ C
}
public static void main(String[] args) {
new second().run(args);
}
}
When I start the second class, everything runs fine, the parser does it's job with both the second and first classes, but when I try to extract the data found by the first class, it's null. I figure once the first class's main method finishes after 'B', once 'A' goes out of scope, everything from the first class is lost. So when I try to get data at 'C', there's nothing there. If this is the case, is there any way I can access the first class's data before it's lost?
I don't have as much knowledge about multithreaded programs so this may just be a very simple solution that I've never seen before.
The reason this doesn't work is that each main method creates its own instance of the class and uses it locally. This has nothing to do with threads, and in fact as far as I can tell your program doesn't actually use multithreading at all.
To fix it, don't call from one main method to the other. In fact, don't even have two main methods in the first place, there's almost never a reason to have more than one. Instead, simply call run directly, like this:
public void run(String[] args) {
// parse the file from args and store data
firstClass = new first();
firstClass.run(args);
dataFromFirst = firstClass.getSomeData();
}
I have some doubt on how this works, consider a simple Java program:
package com.example;
public class Test {
public static void main(String[] args) {
Test t = new Test(); (1) <---- How is this possible
t.print();
}
public void print() {
System.out.println("This is demo");
}
}
This is pretty straightforward program.
However, I have doubt at (1). We are creating an instance of Test, but this is still in the definition of Class Test. How is this possible?
Any explanation to help this would be great.
The instance will be created at run-time.
By then, compile-time is over and all of the code of your application (including all class definition) will be "ready".
Even if you call a constructor of a class that has not been encountered by the JVM up to that point, it will dynamically load the class (in its entirety) before executing the constructor call. Note that a) this might actually fail at run-time, in which case you get a ClassNotFoundError, and b) that cannot happen in your case, because you are calling the constructor of the class from itself (so it must have been loaded already).
The compiler does not run any of your code (not even things like static initializers) during compilation.
But it does make sure (during compilation) that every method or constructor that you are trying to call does in fact exist. Again, this could theoretically fail at runtime (if you mess up class files), in which case you would get a NoSuchMethodError.
First We have to Compile this Porgram using javac After Compilation It will give a Class File.
Now time to Execute Your Class Using java which Invokes JVM and load the Class File to the Class Loader.
java fileName.Class
And here
public static void main(String[] args) {
Test t = new Test(); (1) <---- How is this possible
t.print();
}
All we know static Content (either it is Variable or Method In Java) Of class loaded when ClassLoader loads a Class
As You see Main Method is a static Method. and So, It will Automatically Load into the ClassLoader with class File.
Now JVM First find the public static void main(String... args) in class. Which is a static Content means Its a part of Class but not a part of Class Instance. There is no need of Class Instance to Invoke this MainMethod`.
main(String... args) will be Invoked without getting Instance of the Class. In that Main Method , Your Class is Getting Instantiated
Test t = new Test(); \\here t is reference Variable to Test Class Object.
Now Because Class is loaded into the class Loader new Test(); will create a New Object in Heap memory Area of JVM and your method
public void print() {
System.out.println("This is demo");
}
will be invoked using t.print() Which is a Instance Method (Not Static), So It needs Class Instance to Invoke print() Method.
Q: Test t = new Test(); (1) <---- How is this possible
A: Because of the "static" in public static void main(String[] args)
The "static" means that method "main()" is independent of any specific class object.
You can create any class object you want - including a new "Test" object.
One of the benefits of defining "main" to be static is that you can use "main()" as a test method for the class. Each class can have it's own "main", and you can test each class individually by specifying that class in your Java command line.
For example:
public class MyClass {
public int add2(int n) {
return n + 2;
}
public static void main (String[] args) {
MyClass unitTest = new MyClass ();
System.out.println ("add2(2)=" + unitTest.add2(2));
System.out.println("Expected result=4");
}
}
Then test as follows:
javac MyClass.java
java MyClass
add2(2)=4
Expected result=4
This question has actually been asked and answered many times. For example:
Why is the Java main method static?
==================================================================
Here are a few more examples that illustrate the point:
public class CreateMyself {
private int value = 0;
private static CreateMyself m_singleton = null;
// EXAMPLE 1: You can legally create an instance in the constructor ...
public CreateMyself () {
value++;
// CreateMyself o = new CreateMyself (); // BAD!!! This will cause infinite recursion and crash your stack!!!
System.out.println ("Leaving constructor, value=" + value + "...");
}
// EXAMPLE 2: You can legally create another instance in a normal class member
public void createAnother() {
// But ... WHY??? Is there anything you can't do directly, in your own instance?
CreateMyself newInstance = new CreateMyself ();
System.out.println ("Leaving createAnother, value=" + value + "...");
}
// EXAMPLE 3: This is a common idiom for creating a "singleton"
// NOTE: for this to work, you'd also make the constructor PRIVATE (or protected), so the client *must* call "getInstance()", instead of "new".
public static CreateMyself getInstance () {
if (m_singleton == null) {
m_singleton = new CreateMyself ();
}
System.out.println ("returning singleton instance...");
return m_singleton;
}
// EXAMPLE 4: Creating an instance in "static main()" is a common idiom
public static void main (String[] args) {
CreateMyself newInstance = new CreateMyself ();
newInstance.createAnother ();
}
}
There are many other possible uses. For example, maybe you'll have a static method that does a database lookup and returns a list matching objects.
Note that most of the cases where it's really useful for a class to have a method where it creates an instance of itself are probably static methods.
I came across a code which my colleague uses inside an eventListner, which is :
private void someActionPerformed(java.awt.event.ActionEvent evt) {
new className().methodName(); //public class and public void methodName()
}
I was pretty sure that :
private void someActionPerformed(java.awt.event.ActionEvent evt) {
className ref = new className(); //public class and public void
ref.methodName();
}
is the better option than his, as the previous method instantiates a class every time it is called.
Am I wrong? Any suggestion is appreciated, Please correct me if I am wrong
.
Both do the same thing, however one of them (the first) is 1 line shorter.
Your approach is usually recommended when you need to go through more than 2-3 objects, so new Foo().getBar1().getBar2().doStuff() is usually not recommended since it can degrade into spaghetti code and hinder the understandability of the code.
The first code-sample instantiates a new Object of Type className.methodName.
For this to work, methodName has to be a static nested class of Type className.
Attention: This could as well be a typo. Did you mean new className().methodName()?
The second sample creates a new instance of className and calls its method methodName.
Some example code:
public class Test {
public static void main(String[] args) {
new Test.test(); // instantiates the inner class
Test t = new Test(); // instantiates Test
t.test(); // calls method #test of Test-instance
}
public String test() {
return "Test";
}
public static class test {
}
}
In order to judge what's the best solution your example does not give enought information. Is the method some static utility code or is an instance of className useful? It depends...
Whenever an object is instantiated but is not assigned a reference variable, it is called anonymous object instantiation.
With anonymous object you can call it's instance method also:
new className().methodName();
In your case this is the anonymous object which doesn't have reference variable.
In the statements:
className ref = new className();
ref.methodName();
ref is the reference variable to hold the className object, so you can call instance methods of className on ref variable.
The benefit of using anonymous notation is, if you want to do only limited (may be calling single method and so on..) operation with the underlying object the it is a good approach. But if you needs to perform more operation with the underlying object then you need to keep that object in a reference variable so that you can use that reference to perform multiple operations with that object.
Regarding the performance there are not much difference as both are in methods scope, as soon as method completes both the objects are valid candidates for the garbage collection.
Both the methods instantiates a class in the code. If you want to reuse the class object every time the method is called, you can declare it as a member of the class where the method resides. For eg:
class AnotherClass{
private ClassName ref;
AnotherClass(){
ref = new ClassName()
}
private void someActionPerformed(java.awt.event.ActionEvent evt) {
ref.methodName();
}
}
This way, everytime your method someActionPerformed is called on an object of AnotherClass, it will reuse the ref object instead of instantiating it everytime.
About the edit,
public class ClassName {
static class InnerClass{
// A static inner class
}
public void methodName() {
// A method
}
}
class AnotherClass{
private void someActionPerformed(java.awt.event.ActionEvent evt){
// This creates an instance of the inner class `InnerClass`
new ClassName.InnerClass();
// However I believe, you wanted to do:
new ClassName().methodName();
}
}
new className.methodName(); --> if you are using this convention in your code then calling another method name will result to different object's method name and you lose your values.
className ref = new className();
ref.methodName(); -> here you are creating a reference and make assiging a newly created object and you are calling the method's on it. Suppose if you want to call another method on the same object it will helps.
The first approach they will mostly use for listenere which is anonymous class.
Both options create a new Class every time they are called. The advantage of the second over the first option would be if you wanted to reuse that class later in the method.
IMHO this is a little bit more understandable code for the answer provided by DaniEll
public class Test {
public static void main(String[] args) {
new Test.test(); // instantiates the inner class
Test t = new Test(); // instantiates Test
t.test(); // calls method #test of Test-instance
}
public void test() {
System.out.println("Outer class");
}
public static class test {
public test() {
System.out.println("Inner class");
}
}
}
Why does the following code print "YO"? Whose printYo() is being called? I would think that this code would not compile because printYo() is private to t.
public class Test {
private void printYo() {
System.out.println("YO");
}
public void doubleTrouble(Test t) {
t.printYo();
}
public static void main(String[] args) {
Test test = new Test();
test.doubleTrouble(new Test());
}
}
What can I do to make sure the outer object doesn't mutate the argument class?
printYo() is private to t
No. That method is private in regards to the class Test. Any piece of code within Test can use it.
What can I do to make sure the outer object doesn't mutate the argument class?
Java does not have any built in mechanism to refuse access to members on a per instance basis. (If that is what you meant.)
You are calling the method with in the class , which sound correct for the output . Even if you call the main method from different class it gives the same output.