How to test a function which modify a mock member? [duplicate] - java

This question already has answers here:
How to write a Unit Test?
(5 answers)
Closed 4 years ago.
I have a problem with Mockito. I have two different class. My purpose is test “setChanges” function. this is my first class :
class M {
private String a;
private String b;
private boolean c = false;
public String getA() {
return a;
}
public void setA( String _a ) {
a = _a;
}
public String getC() {
return c;
}
public void setC( final boolean imp ) {
c = imp;
}
}
this is the main class which has “setChanges” function:
class MyMainClass {
private String getMyA() {
return "Data";
}
private static void setChanges(final M m) {
if (getMyA().equals(m.getA())){
m.setC(true);
}
}
}
How can I test "setChanges"? Which means that if getA() returns "Data", How can I check getC() that should be "true"?

Thanks, It works with this code :
#Test
public void testsetChanges(){
MyMainClass mmc = new MyMainClass ();
M m = new M();
m.setA("Data");
Method method = MyMainClass.class.getDeclaredMethod(
"setChanges",
M.class
);
method.setAccessible(true);
method.invoke(method, m );
assertTrue(m.getC());
}

Pass in an instance of M which satisfies (or doesn't satisfy) getMyA and validate that M#getC returns true (or false, depending on what you're testing). No mocks required.

Related

Java: Calling an instanced getter from another class return null

I'm new into Java and want to improve my OOP skills.
Therefore I try to write all my "first programmes" object-oriented.
Anyway... I started a small primitives test programme:
public class Primitives {
byte b;
private void setByte (byte b)
{
this.b = b;
}
public byte getByte()
{
return b;
}
short s;
private void setShort (short s)
{
this.s = s;
}
public short getShort()
{
return s;
}
int i;
private void setInteger (int i)
{
this.i = i;
}
public int getInteger()
{
return i;
}
long l;
private void setLong (long l)
{
this.l = l;
}
public long getLong()
{
return l;
}
float f;
private void setFloat (float f)
{
this.f = f;
}
public float getfloat()
{
return f;
}
double d;
private void setDouble (double d)
{
this.d = d;
}
public double getDouble()
{
return d;
}
boolean bool;
private void setBoolean (boolean bool)
{
this.bool = bool;
}
public boolean getBoolean()
{
return bool;
}
char c;
private void setChar (char c)
{
this.c = c;
}
public char getChar()
{
return c;
}
String str;
private void setString (String str)
{
this.str = str;
}
public String getString()
{
return str;
}
public static void main(String[] args) {
Primitives prim = new Primitives();
prim.setBoolean(true);
//prim.setByte(42);
//prim.setChar("ft");
prim.setDouble(42.42);
//prim.setFloat(42);
prim.setInteger(42);
prim.setLong(424242);
//prim.setShort(0);
prim.setString("fourtytwo");
//System.out.println(integer.getInteger());
}
}
Afterward, I'm trying to call my getters in another class "Main":
public class Main {
public static void main(String[] args)
{
Primitives object = new Primitives();
int objectInt = object.getInteger();
String objectString = object.getString();
System.out.println(objectInt);
System.out.println(objectString);
}
}
My output is
0
null
How does this come?
I mean, I instanced (getInt for example) before, why I received 0?
I know there must 1000 answers here but I couldn't find any proper one.
Another question:
Why do I get "The method setByte(byte) in the type Primitives is not applicable for the arguments (int)" in my Setter? (that's why I comment some of the types out)
You should call the setter methods and set the value before you get them.
The problem with your code is : You are having two main classes and looks like you are running the one in the Main class which doesn`t initiate your variable.
The other main method inside your Primitives class never get executed, so you have not initiated your variables actually!
Each application should have one main class, and only one

Calling a method from main method [duplicate]

This question already has answers here:
cannot make a static reference to the non-static field
(7 answers)
Closed 7 years ago.
When I am calling a method directly from main method, it is not allowed. However, when I am calling the same method from the constructor of a class, it is allowed.
The allowed version;
public class App {
Integer firstVariable;
Integer secondVariable;
public static void main(String[] args) {
App obj = new App(3, 2);
}
public App(Integer firstVariable, Integer secondVariable) {
this.firstVariable = firstVariable;
this.secondVariable = secondVariable;
this.calculate(firstVariable, secondVariable);
}
public int calculate(int a, int b) {
int result = a + b;
return result;
}
}
The disallowed version;
public class App {
Integer firstVariable;
Integer secondVariable;
public static void main(String[] args) {
App obj = new App(3, 2);
obj.calculate(firstVariable, secondVariable);
}
public App(Integer firstVariable, Integer secondVariable) {
this.firstVariable = firstVariable;
this.secondVariable = secondVariable;
}
public int calculate(int a, int b) {
int result = a + b;
return result;
}
}
I know it is "Cannot make a static reference to the non-static field firstVariable" error. My question is; In both code blocks, the same thing is done but what is the difference between them?
The issue isn't your method. The issue is that your variables (the arguments that you're trying to pass) are being referenced from a static context.

Please Explain Java 8 Method Reference to instance Method using class name

public interface MyFunc<T> {
boolean func(T v1, T v2);
}
public class HighTemp {
private int hTemp;
HighTemp(){
}
public HighTemp(int ht) {
this.hTemp = ht;
}
boolean sameTemp(HighTemp ht2){
return hTemp == ht2.hTemp;
}
boolean lessThanTemp(HighTemp ht2){
return hTemp < ht2.hTemp;
}
}
class InstMethWithObjRef {
static <T> int counter(T[] vals, MyFunc<T> f, T v){
int count = 0;
for (int i = 0; i < vals.length; i++) {
if(f.func(vals[i], v)) count++;
}
return count;
}
public static void main(String[] args) {
int count;
//Create an array of HighTemp objects.
HighTemp[] weekDayHighs = {new HighTemp(89), new HighTemp(82),
new HighTemp(90), new HighTemp(89),
new HighTemp(89), new HighTemp(91),
new HighTemp(84), new HighTemp(83)};
count = counter(weekDayHighs, HighTemp::lessThanTemp,new HighTemp(89));
System.out.println(count);
}
}
Please explain how
boolean sameTemp() is compatible with func() in Functional interface.
sameTemp() method got implemented on func() in Functional Interface.
count = counter(weekDayHighs, HighTemp::sameTemp, new HighTemp(89)); is working
Please Explain All points separately.
Equivalent lambda expression of HighTemp::lessThanTemp is
(highTemp1, highTemp2) -> {
return highTemp1.lessThanTemp(highTemp2);
}
This is one of the features of Java8 named Reference to an Instance Method of an Arbitrary Object of a Particular Type
Consider following example,
interface FIface<T> {
int testMethod(T a, T b);
}
class Test2 {
private String str;
Test2(String str) {
this.str = str;
}
int ok(Test2 test2) {
System.out.println("Currnet String : "+ this.str);//Refer to t1
System.out.println("Test String : "+test2.str);//Refer to t2
return 0;
}
}
public class Test {
public static <T> int checkCall(T t1, T t2, FIface<T> fiFace) {
//Here Test2 :: ok is equivalent to t1.ok(t2)
return fiFace.testMethod(t1, t2);
}
public static void main(String[] args) {
checkCall(new Test2("a"), new Test2("b"), Test2 :: ok);
}
}
OUTPUT
Currnet String : a
Test String : b
Note here that Test2 :: ok is valid for the call even ok method is not static.
When you call the method checkCall for the functional interface you still have two arguments which are t1 and t2 and for that valid lambda expression can have parameters as (Test t1, Test t2) so your method Test2 :: ok here becomes valid for the call. Internally it works this way t1.ok(t2).
So, fiFace.testMethod(t1, t2); will will invoke method as t1.ok(t2)
For starters I'm not a professional programmer. I too had a great difficulty in understanding the so called "Reference to an Instance Method of an Arbitrary Object of a Particular Type" I think this might be helpful for somebody who comes here from a google search.
I understood it a little bit with the help of lambda expressions.
In your code HighTemp::lessThanTemp as a Lambda expression would look like (x,y)->{x.lessThanTemp(y);} Replacing the method reference with this lambda expression would produce the same result. The above Lambda expression or the method reference both tell the interface method what to do.
When you use the method reference it tells the interface method to use the referred method from the given class, to carryout its function. Therefore if you convert HighTemp::lessThanTemp to English words it would sound something like "implement the lessThanTemp method form the class HighTemp as the implementation of the interface function". As you might've noticed in that case the return types and the argument types should be compatible. Otherwise you cannot implement an interface.
I would provide you another simple example code. More examples helps to understand this concept.
interface myint{
int returnit(Test t ,int y);
}
class Test{
int x=0;
public Test(int x){
this.x=x;
}
public int addNumbers(int y){
return x+y;
}
public int subtractNumbers(int y){
return x-y;
}
}
public class myclass{
private static void myMethod(Test t,myint inf,int y){
int x=inf.returnit(t, y);
System.out.println(x+"");
}
public static void main(String[] args){
myMethod(new Test(4),Test::addNumbers,7);
myMethod(new Test(4),Test::subtractNumbers,7);
}
}
Output would be:
11
-3
This is the simplest way I could imagine it. See how return types and argument types gets matched using the above sentence pattern. Spend some time on it.
This is the Interface
package learninglambdaexp;
#FunctionalInterface
public interface TempInterface {
public boolean validTemp(Temperature temp);
}
This is the class
package learninglambdaexp;
public class Temperature {
private int temp;
public Temperature(int temp) {
this.temp = temp;
}
public boolean isEvenTemp() {
return temp % 2 == 0;
}
public boolean isOddTemp(){
return !isEvenTemp();
}
}
This is the Class with the Main Method
package learninglambdaexp;
import java.util.ArrayList;
import java.util.List;
public class AnotherMainClass {
public static void main(String[] args) {
List<Temperature> tempCollection = new ArrayList<>();
tempCollection.add(new Temperature(100));
tempCollection.add(new Temperature(20));
tempCollection.add(new Temperature(30));
tempCollection.add(new Temperature(40));
tempCollection.add(new Temperature(50));
tempCollection.add(new Temperature(60));
tempCollection.add(new Temperature(70));
int k1 = countVariation(tempCollection, Temperature::isEvenTemp);
//int k2 = countVariation(Temperature::lowTemp);
System.out.println(k1);
// System.out.println(k2);
}
private static int countVariation(List<Temperature> tempCollection, TempInterface ti) {
int count = 0;
for (Temperature eachTemp : tempCollection) {
if (ti.validTemp(eachTemp)) { // (eachTemp) -> {return eachTemp.isEvenTemp();};
count++;
}
}
return count;
}
}
With one argument its easier to understand
Please, correct me if I am wrong, but the way I think about this type of method references (Reference to an Instance Method of an Arbitrary Object of a Particular Type) is that when we pass a method reference, in this case to the counter method, the instance of anonymous class which implements MyFunc interface is created. Then, inside this anonymous class, we override func method which is passed two parameters. And then inside the func method, lessThanTemp method is called like this:
v1.lessThanTemp(v2);
So for me this concept looks something like this:
public class Demo {
public static void main(String[] args) {
AnonymousClass an = new AnonymousClass();
System.out.println(an.apply(new SomeClass(3), 4));
}
}
interface SomeInterface {
int apply(SomeClass obj, int n);
}
class SomeClass {
private int n;
SomeClass(int n) {
this.n = n;
}
int add(int n) {
return this.n + n;
}
}
class AnonymousClass implements SomeInterface {
#Override
public int apply(SomeClass o, int n) {
return o.add(n);
}
}

Code gives NullPointerException [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I have made five classes (as shown below). When I run my code it gives me "NullPointerException"
First class
public class PasPosition {
boolean lessThanThirty;
boolean ThirtyToFifty;
boolean FiftyToHundred;
public PasPosition(boolean value1, boolean value2, boolean value3)
{
lessThanThirty = value1;
ThirtyToFifty = value2;
FiftyToHundred = value3;
}
}
Second Class
public class CssPosition {
boolean lessThanThirty;
boolean ThirtyToFifty;
boolean FiftyToHundred;
public CssPosition(boolean value1,boolean value2, boolean value3)
{
lessThanThirty = value1;
ThirtyToFifty = value2;
FiftyToHundred = value3;
}
}
Third class
public class SiteData {
PasPosition pas;
CssPosition css;
}
last class
public class Test {
SiteData[] sitedata = new SiteData[2];
public void test()
{
for(int i=0;i<sitedata.length;i++)
{
System.out.println(sitedata[i].css.FiftyToHundred);
System.out.println(sitedata[i].css.ThirtyToFifty);
System.out.println(sitedata[i].css.lessThanThirty);
System.out.println();
}
}
}
It seems that you didn't init the objects.
You must know that in java, an object in a class will not be automatically inited. You must use new operator.
public class SiteData {
PasPosition pas=new PasPosition(false,false,false);
CssPosition css=new CssPosition(false,false,false);//use your own initial value
}

Value "null" by default in String

I have this class
public class Model {
private String a;
private String b;
public synchronized String getA() {
return a;
}
public synchronized void setA(String a) {
this.a = a;
}
public synchronized String getB() {
return b;
}
public synchronized void setB(String b) {
this.b = b;
}
}
I try to get the value of a, and I know that by default this variable is initialize to null. But, is it possible that if I call the getA() method, afterwards this variable has the String "null" on it (not null but the String)? So a.equals("null") == true.
public static void main(String[] args) throws ParseException {
Model m = new Model();
String test = m.getA();
m.getA().equals("null");//No Exception occurs
}
And in fact the code where I eval the String is part of an Android Application:
mAirline = (Airline) extras.getSerializable("airline");
#SuppressWarnings("unused")
String test = mAirline.getPhone(); //(1)
String test2 = mAirline.getHref(); //(2)
If I check mAirline in (1) mAirline has it fields in null, but in (2) has some of them to "null" And my method for get is
public synchronized String getPhone() {
return phone;
}
No, with the code you showed us, it's not possible that you automatically get the String "null".
Note, however, that some methods will convert null to "null". The most notable examples are PrintWriter.println() (as in System.out.println()) and String.valueOf().
System.out.println(null);
System.out.println("null".equals(String.valueOf(null)));
These line will print null (i.e. the 4 characters) and true respectively
Maybe just:
private String a = "null";
Why don't you just check if the string is not null?
Model m = new Model();
String test = m.getA();
if(test==null) {
//is null
} else {
//is not null
}
You can also alter the getter method, so it returns your default value if the field is not initialized:
public class Model {
private String a;
public synchronized String getA() {
//if a is null, return "null", else return a
return a==null?"null":a;
}
}
The method String.valueOf() returns "null" if the argument is null or the argument itself if it is a String that is different from null.
Model m = new Model();
String test = m.getA();
if (String.valueOf(a).equals("null")) //No Exception occurs
but this is kind of cryptic, pretty hard to understand what you want to do.
Check for null directly, much easier to read:
Model m = new Model();
String test = m.getA();
if (a == null || a.equals("null")) //No Exception occurs
So you mean, the value of a is the string null, rather than a pointer with value null? That well never happen, unless you set it like that using setA("null");.
If you want a to be initialized as null, write a constructor:
public Model() {
a = "null";
}
This will fix the problem for you. If the variable is null you will return "null" and if not you will return the value.
public class Model {
private String a;
private String b;
public synchronized String getA() {
return (if (a ==null) ? "null" : a);
}
public synchronized void setA(String a) {
this.a = a;
}
public synchronized String getB() {
return (if (b ==null) ? "null" : b);
}
public synchronized void setB(String b) {
this.b = b;
}
}

Categories