I just want to know is there a way in junit or with the help of any mocking frameworks,to just test the constructor of a class.In a way to just test whether a constructor is invoked like how we test for a method is invoked using verify,can we apply it to constructor.I have seen in many post,where people test the constructor by testing the value of the fields in the class after constructor initialization.
Like
Public ClassName{
private Class x;
#Inject
ClassName(Class x){
this(x.getObjDriver);
}
ClassName(Driver d){
do something...
}
public int getValueOfX{
return x;
}
and in the test class they test this constructor ClassName by calling the construcotr with a argument value for x and then using the getValueOfX method in their assert statement to check the value of x thereby somehow testing the constructor call.
I was thinking doing this in a way not using this approach
is there a way to test the ClassName(Class x) constructor? And also verify in the process the ClassName(Driver d) constructor was also called?
Related
Okay, so, I have a kind of specific problem. I have a class structure similar to this (simplified for simplicity purposes).
class A {
A() {
// long initialization
}
A(int someValue) {
this();
// do something with someValue
}
}
class B extends A {
B() {
super();
// some long initialization
}
B(int someValue) {
// What should i do here ?
}
}
But now, i want to be able to construct class B using the second constructor. But the second constructor should call the super(someValue) constructor to make use of the someValue parameter, but at the same time it needs to call this() to to not have to duplicate the initialization of this class. The problem is that i can't call this and super constructors at the same time.
Also I can't extract the initialization in first constructor to some method, because I have some final fields that needs to be initialized inside the constructor to stay final.
The usual solution is to flip the dependencies between your constructor: call super(someValue) inside B(int someValue), and call this(DEFAULT) inside B(). However, you’ll need to figure out a valid DEFAULT for this case — that is, a default value for someValue that can be used by the parameter-less B() constructor (null often works).
If A() and A(int someValue) do fundamentally different things this won’t work, but that’s a sign that the class A is probably poorly designed (in other words: it should be feasible).
As an alternative, just have both B() and B(int someValue) call a method that performs the rest of the initialisation, after calling super()/super(someValue).
I found something strange in my project. I create a test class using JUnit to test my service layer. The service layer itself is not my question. My problem is, I don't know why after I assigned a value to an int variable in my first test method, and then when I try to use that value in the second test method, the variable value is 0
Executed in order because I use #FixMethodOrder(MethodSorters.NAME_ASCENDING)
int id;
#Test
public void firstMethodToTest() {
id = 10;
System.out.println(id); // here printed correctly 10
}
#Test
public void secondMethodToTest() {
System.out.println(id); // here printed 0
}
I also try to change int to Integer but it returns null not 0 anymore.
I wonder if in JUnit Test class like this, Java variable acts differently.
Thanks.
Thanks to #Ivan for giving me a clue to the answer
For each test method (the method annotated with #Test), a new instance of YourTestClass will be created. This is the behavior of Junit.
So, the point is if you want to use a class member for all test methods, just declare the variable as static. In my case: static int id;
When I use #InjectMocks, an exception was occurred. My code is shown below:
class A {
private X x;
private Y y;
public A(String ip, int port) {
this(someMethodCall(ip, port)); //
}
private A(X x) {
this.x = x;
this.y = new Y();
}
}
UT:
public class ATest() {
#InjectMocks A a;
#Mock X x;
#Mock Y y;
#Test ...
}
it will throw an NPE, can someone help me?
org.mockito.exceptions.base.MockitoException: Cannot instantiate #InjectMocks field named 'channel' of type 'class Juinit3.Channel'. You haven't provided the instance at field declaration so I tried to construct the instance. However, the constructor or the initialization block threw an exception: null.
What this exeception is telling you...
You haven't provided the instance at field declaration
In other words, you did not write...
#InjectMocks
A a = new A("foobar", 123);
This would be completely acceptable and will probably solve your problem. Please remember that mocks will NOT be initialized at that point, so it's fine if you really need an example String and int there, but not if you need to put mocks there. In other words, if you had a constructor that took an X and you would write new A(x) here, x would be null, since the #Mock annotation would not have been processed yet.
so I tried to construct the instance
Because there was no instance (because you didn't provide one) it tried to create one, but...
However, the constructor or the initialization block threw an exception: null
So, your constructor throws null. Seems like your someMethodCall relies on the arguments (port, most likely) given not to be null, but since they are String and int, Mockito has no idea what values to use there. Since port is a primitive type and Mockito does not handle those specifically, the problem is probably there - Mockito will try to put null there, which will throw an exception.
If your constructor matched X and Y, for example, Mockito would probably try to put the mocks there, but it doesn't. The constructor wants String and int and there are no mocks for them, so Mockito can only use default values and those are null, which is a problem in case of port (because of int).
So, what's the solution?
1) Either make your constructor null-safe, allowing to give a null-port there (and make sure that the ip string is also handled in a null-safe way).
2) Use the thing you didn't use:
#InjectMocks
A a = new A("foobar", 123);
In any case, it is not required to have all the depedencies in the constructor, Mockito will do fine injecting them into fields directly. So adding another constructor for X and Y is not a real solution. Of course, generally, constructor injection is preferable over field injection, but that's another topic.
As for your question about which constructor: The documentation says this...
the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only
Edit: Seems that Mockito does not know how to handle primitive fields in constructors, what a shame.
The problem is with your #InjectMocks field. Since you did not initialize it directly like this:
#InjectMocks A a = new A("localhost", 80);
mockito will try to do constructor initialization. In this case it will choose the biggest constructor. In your case it's public A(String ip, int port). If no mock fields as provided that will match the constructor arguments, the mockito will pass nulls as a values for choosen constructor. So in this case the instance is initialized as new A(null, null). In this case you will get NPE, since the second parameter of your constructor is int, and when the null will is going to be unboxed to int the NPE will be thrown.
1) Either create a public non-args constructor or create public A(X x, Y y) constructor.
2) Make sure you use
#RunWith(MockitoJUnitRunner.class)
public class ATest() {
or
#Before
public void init(){
MockitoAnnotations.initMocks(this);
}
I want to create a static method that can be called by a variety of different classes. All classes that will call this method have a method called "evaluate", which I want to call from within the method.
All classes and methods involved are static. The "evaluate" method, however, is implemented differently in each class that has it. How do I call the evaluate method from the specific class that called the method each time?
Thanks!!
Here is psudeo code/ more information
The goal of my project is to implement Newton and Bisection approximation methods to an arbitrary number of sig-figs
Concerning the bisection method specifically - it should be able to work with any evaluatable function
This is not an ideal way to do it, but because of the framework of my assignment (high school teacher), each of my different functions are imbedded in a
static class, as a single method called "evaluate".
The bisection method relies on being able to call the evaluate method over and over again to find zeroes. I want to be able to call each specific class's
evaluate from the separate bisection method.
Example of a evaluation class:
//evaluate the function x^2+5x+3
public class Problem1{
public void main(String[] args){
//code here
//call bisectionMethod() here
}
//various other methods
//the one that i'm concerned about
public static double evaluate(double input){
//return output for x^2+5x+3
}
} //several classes like this, with different functions
public class Bisection{
//filler methods
//this one:
public static double[] bisectionMethod(){ //don't know if it should have inputs - it has to be able to figure out which eval it's using
//do the bisection method
call evaluate(double input) here
}
}
This is a restriction that you cannot put static methods into interface. Workaround is to use Java Reflection API:
public Object callStaticEvaluate(Class<?> clazz, double input) throws Exception {
return clazz.getMethod("evaluate", double.class).invoke(null, input);
}
What is reflection and why is it useful?
Given Java 8 syntax there is a third way besides using interfaces and reflection:
In Bisection write
import java.util.function.DoubleUnaryOperator;
public class Bisection {
public static double[] bisectionMethod(DoubleUnaryOperator evalFn, <other args>)
// invoke the function
double in = ...;
double out = fn.applyAsDouble(in);
...
}
}
and invoke Bisection using a method handle to your static evaluation function:
Bisection.bisectionMethod(Problem1::evaluate)
You cannot do it via any clean way.. OOP does not support any of such structure. You have to use reflection. Invoking a static method using reflection
so it would be -
public static <T extends XXX> void evaluate(Class<T> c){
// invoke static method on c using reflection
}
Heres some sample code,
class Base
{
private int val;
Base() {
val = lookup();
}
public int lookup() {
//Perform some lookup
// int num = someLookup();
return 5;
}
public int value() {
return val;
}
}
class Derived extends Base
{
private int num = 10;
public int lookup() {
return num;
}
}
class Test
{
public static void main(String args[]) {
Derived d = new Derived();
System.out.println("d.value() returns " + d.value());
}
}
output: d.value() returns 0 // I expected 10 as lookup() is overridden, but not 0! can someone clarify this?
The initialization of Derived's instance variables has not happened at the time its lookup method executes. How do I make sure the instance variables of Derived are initialized when its method is called?
Well for a start, that code doesn't compile due to the lack of someLookup method.
Anyway, asides from that I believe your issue is that your expections are invalid because of the way constructors are run hierarchically.
A superclass' constructor is always run before the subclass', and this includes initializers for the subclass' variables (which are really run as part of the constructor). So, when you create your instance of Derived, the following happens:
The Base constructor is invoked first.
lookup() is called, which uses the implementation in Derived.
num is returned, which is the default value at this point because Derived's constructor and initializers have not been run.
val is set to 0.
The Derived initializers and constructor are run - calling lookup from this point on will return 10.
In general, it's a bad idea to call a non-final method from a constructor for exactly this reason, and many static analysis tools will warn you against it. It's similar to letting object references leak during construction, you can end up with an instance that invalidates class-level invariants (in your case, Derived's num is "always" 10 yet it can be seen to be 0 at some points).
Edit: Note that for this particular case, without any additional code, you could resolve the issue by making num a constant:
class Derived extends Base
{
private static final int num = 10;
...
This would actually do what you want, because the static initializer is run when the class is loaded (which has to happen before the constructors are called). This does however assume that it's fine for:
a) all instances of the class to share the same num variable;
b) num never needs to change (if this is true then (a) is true automatically).
In the exact code you've given this is clearly the case, but I expect you may be omitting extra functionality for brevity.
I include this here for comparison and interest, not because it's a workaround to this "issue" in a general sense (because it's not).
The reason you are getting 0 returned is that the constructors Base is being called (and calling lookup in Derived) before 10 is assigned to num in Derived.
To put generally, the base constructor is called before the derived instance fields are initialised.
There are a lot of great answers already on why you can't access subclass fields while constructing the base class, but I think you asked for a how: a working solution for something like this:
public abstract class Animal {
public Animal() {
System.println(whoAmI());
}
public abstract String whoAmI();
}
public Lion() extends Animal {
private String iAmA = "Lion";
public Lion(){super();}
public String whoAmI() {return iAmA;}
}
The practical way is to introduce an init() method on the base class an call it from the subclass's constructor, like:
public abstract class Animal {
private boolean isInitialized = false;
public Animal() {}
void init() {
isInitialized = true;
System.out.println(whoAmI());
}
public abstract String whoAmI();
public void someBaseClassMethod() {
if (!isInitialized)
throw new RuntimeException("Baseclass has not been initialized");
// ...
}
}
public Lion() extends Animal {
private String iAmA = "Lion";
public Lion() {
super();
init();
}
public String whoAmI() {return iAmA;}
}
Only problem is, you can't force subclasses to call the init() method on the base class and the base class might not be properly initialized. But with a flag and some exceptions we can remind the programmer at runtime that he should have called init()...
It is generally a bad idea to call methods in a constructor that can be overriden in a subclass. In your example the following happens:
Derived constructor is called
Base constructor is called as its first action
Base constructor calls lookup
Derived constructor continues and initialies num to 10
Since the subclass constructor is not finished when the base constructor calls lookup, the object is not yet completely initialized and lookup returns the default value of the num field.
Let's take it slowly:
class Test
{
public static void main(String args[]) {
// 1
Derived d = new Derived();
// 2
System.out.println("d.value() returns " + d.value());
}
}
Step 1, you call the (default) constructor on Derived, before setting num = 10, it chains up to Base's constructor, which calls Derived's lookup method, but num has not been set, so val remains uninitialized.
Step 2, you call d.value(), which belongs to Base, and val is unset due to 1, and therefore you get 0 instead of 10.
You have overriden method lookup() in the Derived class, so when the Base constructor is called it calls the method from Derived which body is return num. At the time of Base initialization the num instance variable of the Derived is not yet initialized and is 0. That's why val is assigned to 0 in Base.
If I understood your intentions correctly, you should change the value method in Base to be:
public int value() {
return lookup();
}
The below piece of code is returing 0 (you would expect 10 by looking at the program) when the constructor makes a call to this. The simple reason is that num is not initialized yet and the parent class calls this method.
public int lookup() {
return num;
}