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.
I want to write a method in java which receives an array of objects, checks for some compatibility and return a boolean value true if all meet, otherwise to return a string containing a message to inform user why some of the compatibilities don't meet.
I came up with simplified version of my question as follows:
Suppose you wanna compare cars and in order that comparison make sense you wanna make sure all are of same class, same color, same make.
So what I am trying to get from this method are two:
1- are all care compatible? (boolean using return)
2- if not, why? so to inform user of the reasons(String using throw)
What is the best design pattern for this?
Below is one way of implementing it:
boolean areCarsCompatible(Car [] cars) throws CarException {
String errorMessage = "";
for(Car car:cars){
if (cars done have same color) errorMessage +="Cars dont have same color";
}
for(Car car:cars){
if (cars done have same make) errorMessage +="Cars dont have same make";
}
for(Car car:cars){
if (cars are not all of same class) errorMessage +="cars are not all of same class";
}
if (errorMessage.equals("")){
return true
} else {
throw new CarException (errorMessage);
}
}
to return both boolean and strings
Although you can do this in other (dynamic) programming languages, it's strongly recommended that you don't design your method like this in Java. In Java, types are statically checked and strict, you simply can't return two different types from the same method, and throwing an exception when you intend to return a string is, well, just an ugly hack.
A different matter would be throwing an exception with a message to indicate an error, that's a very common practice and within the good practices of the language. But notice that you wouldn't be "returning both boolean and strings", an exception is intended for error handling.
There is a lot to address here.
First, you are seeking a design, an approach, an algorithm, etc., but please don't call this a design pattern. That term has a very specific meaning.
OK, nitpicking semantics aside, your approach is a bit awkward for a couple of reasons. First, the boolean is sort of useless because you don't care about "falseness." Either it all works, or you get a message of some kind. The value false has no value for you.
The other reason it is awkward is as #OscarLopez suggests. There is no neat way in Java, as in Ruby for example, to return a multi-type value.
I will say though that if you are going to throw an exception, your CarException is getting close to the right approach--if it is a checked exception as it seems. I strongly disagree with #cherouvim (though I didn't downvote) that it should be a RuntimeException. You want the caller to know about it and to have to deal with it.
As for my own suggestions for solutions, I have two:
1) Maintain some notion of the criteria necessary for a Car to be in the collection. Then simply don't add a Car to the collection if it doesn't meet those criteria. In other words, solve the problem by preventing it from ever happening in the first place.
2) Use Enums.
public enum CarFeedback {
ALL_SAME, DIFFERENT_COLORS, DIFFERENT_MAKES, DIFFERENT_CLASSES
}
public CarFeedback checkCars(List<Car> cars) {
//Do checks
return ALL_SAME; //or whichever enum value is appropriate
}
Your method can be void and throw an exception if there are any problems. There is no need for it to return a boolean. The caller should assume that if no exception was thrown then everything is OK. This is exactly how exceptions were designed to be used.
I would rename the method:
void checkCompatibilityOf(Car... cars) throws IncompatibleCarsException
Alternative approach: Inversion of Control
Rather than returning a value from the method, you can ask the method to callback with its answer(s). E.g.
interface CompatibilityListener {
void onSuccess();
void onFailure(String message);
}
This will avoid the need for a boolean return value, and remove the need for exceptions.
You could go further and extract the logic of building the error message too:
interface DifferenceListener {
void onDifferentColor(Car car1, Car car2);
void onDifferentMake(Car car1, Car car2);
//etc.
}
And this method:
public void checkCompatibilityOf(DifferenceListener listener, Cars... cars) {
for (Car car: cars) {
if (...) {
listener.onDifferentColor(car1, car2);
}
if (...) {
listener.onDifferentMake(car1, car2);
}
// etc.
}
}
Inversion of control can be a powerful approach in some cases, although, as Vidya says (in the comment) it's probably over-engineering in your case!
You can do everything you want with JAVA. You can create your own class to get the object with any included values you prefer. See below :
import java.math.BigInteger;
import java.util.Date;
public class BoolVariable {
private static BoolVariable instance;
public static BoolVariable BOOLVARIABLE = getInstance();
private boolean bool;
private char c;
private String s;
private int i;
private double d;
private float f;
private BigInteger bi;
private Date date;
private static BoolVariable getInstance() {
if (instance == null) {
instance = new BoolVariable();
}
return instance;
}
private BoolVariable() {
}
public BoolVariable(boolean bool, char c) {
this.bool = bool;
this.c = c;
}
public BoolVariable(boolean bool, String s) {
this.bool = bool;
this.s = s;
}
public BoolVariable(boolean bool, int i) {
this.bool = bool;
this.i = i;
}
public BoolVariable(boolean bool, double d) {
this.bool = bool;
this.d = d;
}
public BoolVariable(boolean bool, float f) {
this.bool = bool;
this.f = f;
}
public BoolVariable(boolean bool, BigInteger bi) {
this.bool = bool;
this.bi = bi;
}
public BoolVariable(boolean bool, Date date) {
this.bool = bool;
this.date = date;
}
public boolean getBool() {
return bool;
}
public char getC() {
return c;
}
public String getS() {
return s;
}
public int getI() {
return i;
}
public double getD() {
return d;
}
public float getF() {
return f;
}
public BigInteger getBi() {
return bi;
}
public Date getDate() {
return date;
}
public void setBool(boolean bool) {
this.bool = bool;
}
public void setC(char c) {
this.c = c;
}
public void setS(String s) {
this.s = s;
}
public void setI(int i) {
this.i = i;
}
public void setD(double d) {
this.d = d;
}
public void setF(float f) {
this.f = f;
}
public void setBi(BigInteger bi) {
this.bi = bi;
}
public void setDate(Date date) {
this.date = date;
}
public BoolVariable create(boolean bool, char c){
return new BoolVariable(bool, c);
}
public BoolVariable create(boolean bool, String s){
return new BoolVariable(bool, s);
}
public BoolVariable create(boolean bool, int i){
return new BoolVariable(bool, i);
}
public BoolVariable create(boolean bool, double d){
return new BoolVariable(bool, d);
}
public BoolVariable create(boolean bool, float f){
return new BoolVariable(bool, f);
}
public BoolVariable create(boolean bool, BigInteger bi){
return new BoolVariable(bool, bi);
}
public BoolVariable create(boolean bool, Date date){
return new BoolVariable(bool, date);
}
#Override
public String toString() {
return "BoolVariable{" + "bool=" + bool + ", c=" + c + ", s="
+ s + ", i=" + i + ", d=" + d + ", f=" + f + ", bi="
+ bi + ", date=" + date + '}';
}
}
You can call this class in any routine that you want to get double variable like below:
BoolVariable bv = BOOLVARIABLE.create(true, "HERE IS YOUR VARIABLE LIKE INTEGER, STRING ETC");
So then you can get any value like bv.getBool();
One idea is to always return boolean but if a condition is not met then you throw a flavour of RuntimeException describing the problem. The caller of this method should handle that.
I know this question is pretty old but I still think this method will clear up a lot of things given the nature of the question. Particularly where it says "... a method in java which receives an array of objects, checks for some compatibility and return a boolean value true if all meet, otherwise to return a string containing a message to inform user why some of the compatibilities don't meet ..." Judging from the question incompatible cars are not supposed to be an error, it is actually as per design part of the behavior of the program, meaning that the car can be compatible or not and from what you want to do you want to know why it is not compatible. If all my current assumptions are right I would rather write my method to return Boolean and incase the method returns a false cause the cars do not match I create a local methods and property in my class getCompareErrorMsg() and compare_error_msg before returning the false in this given method I set the compare_error_msg to the exact comparison error msg, which from what I understand from your question was what you wanted to return as string. so the caller of the method check for it's Boolean value, if it is false the caller can call the method getCompareErrorMsg() which actually returns a string and do what ever it wants to do with it.
In this method I get string as input and according to the string name I need to return value sometimes its string sometime int ,double,int64 ,bool etc
Since its dynamic type i don't know how to define it in the method return type
and how to add to it the value and how to call to this method that the return type is dynamic ,any idea?
public static ? SwitchInput(String TypeName) {
if (TypeName == "java.lang.String" ) {
Return = "A";
}
else if (TypeName == "int" ) {
Return = 1;
}
else if (TypeName == "double") {
Return = 1.00
}
etc for bool and all the other types
}
Object will be your best bet, unless returned type shares an Ancestor
Example :
public static Object switchInput(String typeName) {
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
Another example with generics
static <T> T switchInput(String typeName){
if ("java.lang.String".equals(typeName)) {
return "A";
}
else if ("int".equals(typeName)) {
return 1i;
}
else if ("double".equals(typeName)) {
return 1.0d
}
}
String str = MyClass.switchInput("java.lang.String")
I have not tested that, this is a simpler version of my first thought about generics
To know what the return type is, you have to find a container where all these types fit in. Obviously, this is Object. You'd have to convert the primitive types to the corresponding object (like int to Integer).
A better approach would be to create a new container class, which holds a generic type <T>. Like
public class SwitchDemo {
public static SwitchInputType<?> switchInput(String typeName) {
if (typeName.equals("java.lang.String")) {
return new SwitchInputType<String>(new String("A"));
} else if (typeName.equals("int")) {
return new SwitchInputType<Integer>(new Integer(312));
}
return null;
}
public static class SwitchInputType<T> {
private T type;
public SwitchInputType(T type) {
super();
this.type = type;
}
public T getType() {
return type;
}
public void setType(T type) {
this.type = type;
}
}
public static void main(String[] args) {
SwitchInputType<?> sit1 = SwitchDemo.switchInput("java.lang.String");
System.out.println(sit1.getType());
SwitchInputType<?> sit2 = SwitchDemo.switchInput("int");
System.out.println(sit2.getType());
}
}
As an ugly solution to your problem, you could set your method to run the type Object. (as Boolean, Integer, Double are all subtypes)
You would have to ensure though that you then inferred the correct type afterwards when using the returned value (using instanceof) and recast it to the correct type.
Can I ask though why you need such a method? This is abusing the notion of a method definition slightly.
public static Object SwitchInput(String TypeName) {
if (TypeName.equals("java.lang.String") ) {
Return = new String("A");
}
else if (TypeName.equals("int") ) {
Return = new Integer(1);
}
else if (TypeName.equals("double")) {
Return = new Double(1.00) ;
}
etc for bool and all the other types
}
And using this code snippet to infer what type it is further on down in your code
if(returned_value instanceof Double)
etc.
I am using Spring MVC 3 and a MappingJacksonHttpMessageConverter to serialize my java objects to JSON when they're sent to my client. My problem is that Java long values are being rounded in the client because Javascript numbers can't handle the precision of long values. To get around this, I'm going to send these fields as strings instead of longs. Is there any way to automatically have Spring convert longs to strings without me having to cast every return value in my controllers?
You could copy object with adding new variable of type String using
import org.apache.commons.beanutils.*;
public class Object {
String a;
Long b;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public Long getB() {
return b;
}
public void setB(Long b) {
this.b = b;
}}
public class Object2 extends Object{
String f;
public String getF() {
return b.toString();
}}
public static void main( String[] args ) throws IllegalAccessException, InvocationTargetException
{
Object m = new Object();
m.setA("aa");
m.setB((long) 22222);
Object2 m2 = new Object2();
BeanUtils.copyProperties(m2, m);
//now you can convert m2 to JSONobject
}
have two strings, String1 = hello String2 = world, I want to call a class Hello and send to the two strings. The class should return a boolean value and a string. If the boolean is true it should do the followig:
System.out.println("Hello to you too!");
Can someone help me out with this code?
First, a terminology problem: you cannot "call a class." You can call a method on a class, such as:
someObject.someMethod(string1, string2);
More to the point, you can't return two different values from a method. You could certainly store two different values in the object and return them from different methods, though. Perhaps a class like:
public class Foo {
protected boolean booleanThing;
protected String stringThing;
public void yourMethod(String string1, String string2) {
// Do processing
this.booleanThing = true;
this.stringThing = "Bar";
}
public String getString() {
return this.stringThing;
}
public boolean getBoolean() {
return this.booleanThing;
}
}
Which would be used as:
someObject.yourMethod(string1, string2);
boolean b = someObject.getBoolean();
String s = someObject.getString();
Having said all that, though, this may not at all be the best way to solve your actual problem. Perhaps you can explain better what you're trying to accomplish. Perhaps throwing an Exception is better than trying to return a boolean, or perhaps there's another solution entirely.
The more detail we have, the better.
You should review your definition of classes but for now I'll assume this is what you meant, comment if this isn't what your looking for:
public class Hello {
private final String first;
private final String second;
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "World";
Hello h = new Hello(s1,s2);
if(h.isHelloWorld()) {
System.out.println("Hello to you too!");
}
}
private Hello(String first, String second) {
this.first = first;
this.second = second;
}
private boolean isHelloWorld() {
return (first.equals("Hello") && second.equals("World"));
//If that scares you then do this instead:
/**
if(first.equals("Hello") && second.equals("World") {
return true;
} else { return false; }
**/
}
}
When you run this program it will always print "Hello to you too!", if you change s1 or s2 it won't print anything.
public class Hello{
boolean val = false;
String str = "";
public Hello(String a, String b){
if(a == "hello" && b == "world"){
this.val = true;
this.str = "hello to you too";
}
}
public static void main(String args[]){
String a = "hello";
String b = "world";
Hello hello = new Hello(a,b);
if(hello.val == true)
System.out.println(hello.str);
}
}