Add values to a Java ENUM for testing purposes - java

I'm trying to make some multi-threading test, using JMockit in a code similar to this one:
class scratch_1 {
public static void main(String[] args) {
for (final Car ex: Car.values()) {
System.out.println(ex.getValue());
}
}
}
enum Car {
A(1);
public int getValue() {
return value;
}
private final int value;
Car(final int value){
this.value = value;
}
}
The problem is that to test this, my for cycle should handle more than one Car (the multi-threading logic happens inside). However, I can't change the enum, because at this point in time we only have 1 car, but will have more in the following springs.
How can I add another Car in runtime, only for testing?
EDIT:
This is what I have tried that didn't work:
new Car(2); -> no new instances of enumarators
Create a second class called SpecialCar with 2 SpecialCars, and replace them during tests.
Class SpecialCar extends -> enums can't be extended
mock the values() method from Car.
so
new Expectations() {
{
car.values();
result = {car.A... }
Problem : no more cars to add to array.

There is Car.values(). So either wait writing the unit test, or:
Add a second Car value, write a the unit tests based on values(), agnostic towards the specific constant.
Remove the second Car value, and check all in into the version control system.
Some test may be disarmed because of the being just one value, and maybe even needs a check on if (Car.values().length != 0).

You can have your enum implement an interface, and have a test enum that also implements that interface, and then pass the class of the appropriate enum into the test.
public interface Vehicle {
public int getValue();
}
public enum Car implements Vehicle {
A(1);
public int getValue() {
return value;
}
private final int value;
Car(final int value){
this.value = value;
}
}
public enum TestCar implements Vehicle {
A(1), B(2);
public int getValue() {
return value;
}
private final int value;
Car(final int value){
this.value = value;
}
}
public void test(Class<? extends Vehicle> clazz) {
for (final Vehicle vehicle : clazz.getEnumConstants()) {
System.out.println(vehicle.getValue());
}
}

Related

Avoiding duplication with classes that have same methods but different types, and extend from other types

I have a bunch of classes like IntLogger, ShortLogger, StringLogger etc for all the types here.
The idea is to overload any methods for the Mutable types such that we log the value whenever it is updated.
These classes look like:
import org.apache.commons.lang3.mutable.MutableInt;
public class IntLogger extends MutableInt {
private final String loggerName;
private MutableInt value;
public IntLogger(String loggerName) {
this.loggerName = loggerName;
}
public IntLogger(String loggerName, int value) {
this.loggerName = loggerName;
this.value = new MutableInt(value);
logValue();
}
public void add(int operand) {
this.value.add(operand);
logValue();
}
// ...
public void setValue(int value) {
this.value = new MutableInt(value);
logValue();
}
private void logValue() {
System.out.println(this.value.toString()); // placeholder functionality
}
}
There are a lot that look exactly like IntLogger, such as FloatLogger which has the exact same methods, just replacing int with float and MutableInt with MutableFloat.
import org.apache.commons.lang3.mutable.MutableString;
public class StringLogger extends MutableObject<String> {
private final String loggerName;
private MutableString value;
public StringLogger(String loggerName) {
this.loggerName = loggerName;
}
public StringLogger(String loggerName, String value) {
this.loggerName = loggerName;
this.value = new MutableInt(value);
logValue();
}
public void setValue(String value) {
this.value = new MutableString(value);
logValue();
}
private void logValue() {
System.out.println(this.value); // placeholder functionality
}
}
This obviously doesn't need methods like add, subtract etc. so this one is simple.
I thought about using an abstract class with generics, but I can't seem to figure out how to use them given we extend from the Mutable types, so I can't do add on a MutableObject<Int> for example.
I thought I could make an abstract class NumberLogger which IntLogger, DoubleLogger etc will extend from, and write all the add etc methods in there using generic types. But again the Mutable issue arises
Any ideas?

Java- Returning different classes based on generic type

I would like to create a class that will take in different types. It should handle some basic operations like .equals() for all given types, but I'd like to create specific implementations for Strings and Booleans for example.
I'd like to use the same constructor but control what happens based on the type.
public class TestObject<T>{
private T value;
public TestObject{
}
public setValue(T value){
this.value=value;
}
public return Type??? getSpecificType(){
if (value instanceof Boolean){
return new TestObjectBoolean(this);
}
if (value instanceof String){
return new TestObjectString(this);
}
}
}
The desired usage below:
TestObject<String> test = new TestObject<String>();
test.setValue("Test");
boolean result = test.getSpecificType().stringSpecificMethod()
TestObject<Integer> test2 = new TestObject<Boolean>();
test.setValue(true);
boolean result2= test2.getSpecificType().booleanSpecificMethod();
I would like the below example to fail to compile:
TestObject<String> test3 = new TestObject<String>();
test.setValue("Test");
boolean result3= test3.getSpecificType().booleanSpecificMethod();
//should not compile because test2 should return a boolean specific class
//with the boolean specific methods
It may seem silly but I would like to avoid calling differently named constructors for different types like this:
TestObjectString test4 = new TestObjectString();
test.setValue("Test");
boolean result4= test4.stringSpecificMethod();
I am lost on how to implement this. Any advice or help on searching additional information on this would be appreciated.
Thank you.
I’m not sure I understand what you’re asking for, but I think you want to make the constructor private, and add public factory methods:
public class TestObject<T> {
private T value;
private final Supplier<? extends TestObject<T>> typeSpecificConstructor;
private TestObject(T initialValue,
Supplier<? extends TestObject<T>> constructor) {
this.value = initialValue;
this.typeSpecificConstructor = constructor;
}
protected TestObject(Supplier<? extends TestObject<T>> constructor) {
this.typeSpecificConstructor = constructor;
}
public boolean test(T valueToTest) {
throw new UnsupportedOperationException(
"Must be implemented by subclasses");
}
public static TestObject<Boolean> newInstance(boolean initialValue) {
return new TestObject<>(initialValue, TestObjectBoolean::new);
}
public static TestObject<String> newInstance(String initialValue) {
return new TestObject<>(initialValue, TestObjectString::new);
}
public TestObject<T> getSpecificType() {
return typeSpecificConstructor.get();
}
public T getValue() {
return value;
}
public void setValue(T newValue) {
this.value = newValue;
}
}
But methods particular to a subtype still won’t be accessible. There is simply no way for a variable whose type is a general superclass to make subclass methods available without casting.
I’m not sure what your intended purpose of getSpecificType() is, but you could probably do away with that method and make things simpler:
public abstract class TestObject<T> {
private T value;
public abstract boolean test(T valueToTest);
public static TestObject<Boolean> newInstance(boolean initialValue) {
TestObject<Boolean> instance = new TestObjectBoolean();
instance.setValue(initialValue);
return instance;
}
public static TestObject<String> newInstance(String initialValue) {
TestObject<String> instance = new TestObjectString();
instance.setValue(initialValue);
return instance;
}
public T getValue() {
return value;
}
public void setValue(T newValue) {
this.value = newValue;
}
}

Best way to avoid explicit casts

I have a class hierarchy like below
Vehicle
|_ TransaportationVehicle has method getLoadCapacity
|_ PassengerVehicle has method getPassengerCapacity
and I have one more class Booking it have a reference to Vehicle.
Now whenever I have to call getPassengerCapacity or getLoadCapacity on vehicle reference I need to type cast vehicle to its concrete implementation like ((PassengerVehicle)vehicle).getPassengerCapacity() and this type of calls spans over multiple parts in the project. So is there any way with which I can avoid these type of casts and my code will look beautiful and clean?
Note: These are not actual classes I have taken these as an example to demonstrate current problem.
Obviously, when booking a Vehicle you need to distinguish at some point whether it’s a TransportationVehicle or a PassengerVehicle as both have different properties.
The easiest way would be to initiate two different Booking processes: one for vehicles that can transport goods, and one for vehicles that can transport passengers. As for how to differentiate between these two types of vehicles: you could add canTransportPassengers() and canTransportGoods() methods to Vehicle, the subclasses would then override these methods to return true where appropriate. Also, this way a vehicle that can transport both is possible, like a train.
If You want to use different method names then You must cast to concrete class.
But if You can make this methods return same type value and have same names You can use polymorphism for it. Create abstract method in Vehicle class and override it in each child.
A quick way I would accomplish this is to create a Generified Booking parent class.
public abstract class Booking<V extends Vehicle> {
protected abstract V getVehicle();
}
public class TransportationVehicleBooking extends Booking<TransaportationVehicle> {
#Override
protected TransaportationVehicle getVehicle() {
return new TransaportationVehicle();
}
}
public class PassengerVehicleBooking extends Booking<PassengerVehicle> {
#Override
protected PassengerVehicle getVehicle() {
return new PassengerVehicle();
}
}
Your Booking class will have all the logic that spans all the booking subclasses and some abstract method each subclasses will need to do effective calculations.
Then all you have to do is have reference to a Booking class and calling the relevant method required without having to worry about the "logistics" (get it) of the booking itself.
I hope this helps.
You method overriding concepts. You need to have all these method in the Parent class and same can be overriden in the child clasees.
You can then access all the methods from super class using Runtime polymorphism
Vehicle
public interface Vehicle {
public int getCapacity();
}
TransaportationVehicle
public class TransaportationVehicle implements Vehicle {
#Override
public int getCapacity() {
return getLoadCapacity();
}
private int getLoadCapacity() {
return 0;
}
}
PassengerVehicle
public class PassengerVehicle implements Vehicle {
#Override
public int getCapacity() {
return getPassengerCapacity();
}
private int getPassengerCapacity() {
return 0;
}
}
USAGE
Vehicle passenger = new PassengerVehicle();
passenger.getCapacity();
Vehicle transaportation = new TransaportationVehicle();
transaportation.getCapacity()
First try to extract an abstract method suitable for all vehicles. If you can't do this you can also use an often forgotten pattern - the visitor pattern. E.g.
Introduce a visitor interface
public interface VehicleVisitor {
public void visit(TransportationVehicle transportationVehicle);
public void visit(PassengerVehicle passengerVehicle);
}
add an accept method to the Vehicle
public interface Vehicle {
public void accept(VehicleVisitor visitor);
}
implement the accept method in the sub classes
public class PassengerVehicle implements Vehicle {
private int passengerCapacity;
public static PassengerVehicle withPassengerCapacity(int passengerCapacity) {
return new PassengerVehicle(passengerCapacity);
}
private PassengerVehicle(int passengerCapacity) {
this.passengerCapacity = passengerCapacity;
}
public int getPassengerCapacity() {
return passengerCapacity;
}
#Override
public void accept(VehicleVisitor visitor) {
visitor.visit(this);
}
}
public class TransportationVehicle implements Vehicle {
private int loadCapacity;
public static TransportationVehicle withLoadCapacity(int loadCapacity) {
return new TransportationVehicle(loadCapacity);
}
private TransportationVehicle(int loadCapacity) {
this.loadCapacity = loadCapacity;
}
public int getLoadCapacity() {
return loadCapacity;
}
#Override
public void accept(VehicleVisitor visitor) {
visitor.visit(this);
}
}
implement a visitor...
public class LoadSupported implements VehicleVisitor {
private boolean supported;
private int load;
public LoadSupported(int load) {
this.load = load;
}
public boolean isSupported() {
return supported;
}
#Override
public void visit(TransportationVehicle transportationVehicle) {
int loadCapacity = transportationVehicle.getLoadCapacity();
supported = load <= loadCapacity;
}
#Override
public void visit(PassengerVehicle passengerVehicle) {
supported = false;
}
}
...and use it
public class Main {
public static void main(String[] args) {
TransportationVehicle transportationVehicle1 = TransportationVehicle
.withLoadCapacity(5);
TransportationVehicle transportationVehicle2 = TransportationVehicle
.withLoadCapacity(10);
PassengerVehicle passengerVehicle = PassengerVehicle
.withPassengerCapacity(5);
LoadSupported loadSupported = new LoadSupported(7);
supportsLoad(transportationVehicle1, loadSupported);
supportsLoad(transportationVehicle2, loadSupported);
supportsLoad(passengerVehicle, loadSupported);
}
private static void supportsLoad(Vehicle vehicle,
LoadSupported loadSupported) {
vehicle.accept(loadSupported);
System.out.println(vehicle.getClass().getSimpleName() + "[" + System.identityHashCode(vehicle) + "]" + " does"
+ (loadSupported.isSupported() ? " " : " not ")
+ "support load capacity");
}
}
The output will be something like this
TransportationVehicle[778966024] does not support load capacity
TransportationVehicle[1021653256] does support load capacity
PassengerVehicle[1794515827] does not support load capacity
Assuming that passenger capacity is always an integer and load capacity could very well a big number depending on what is the unit for load. I would go ahead and create Vehicle class as follow:
class Vehicle {
Number capacity;
public Number getCapacity() {
return capacity;
}
public void setCapacity(Number capacity) {
this.capacity = capacity;
}
}
The reason I am using Number is so that I then use Integer in PassengerVehicle class and Double in TransporatationVehicle and that is because Integer and Double are subtype of Number and you can get away with a cast.
class TransportationVehicle extends Vehicle {
#Override
public Double getCapacity() {
//all I have to do is cast Number to Double
return (Double) capacity;
}
#Override
public void setCapacity(Number capacity) {
this.capacity = capacity;
}
}
Similarly the PassengerVehicle class as follow:
class PassengerVehicle extends Vehicle {
#Override
public Integer getCapacity() {
//Cast to Integer and works because Integer is subtype of Number
return (Integer) capacity;
}
#Override
public void setCapacity(Number capacity) {
this.capacity = capacity;
}
}
You can then use above classes to create vehicle object as follow:
public class Booking {
public static void main(String[] args) {
//
Vehicle transportationVehicle = new TransportationVehicle();
//assigning Double to setCapacity
transportationVehicle.setCapacity(new Double(225.12));
Vehicle passengerVehicle = new PassengerVehicle();
//assigning Integer to setCapacity
passengerVehicle.setCapacity(5);
System.out.println(transportationVehicle.getCapacity());
// output: 225.12
System.out.println(passengerVehicle.getCapacity());
// output: 5
}
}
On the side notes if you try to pass TransportationVehicle anything but Number or Double then you will get Exception and similarly if you pass PassengerVehicle anything but Number or Integer you will get exception.
I know that I am deviating from the scope of your question but, I really want to show how you can make your methods generics. This allow you to decide to return type of getCapacity() during coding which is very flexible. See below:
class Vehicle<T> {
//generic type T
T capacity;
//generic method getCapacity
public T getCapacity() {
return capacity;
}
//generic method setCapacity
public void setCapacity(T capacity) {
this.capacity = capacity;
}
}
class TransportationVehicle<T> extends Vehicle<T> {
#Override
public T getCapacity() {
return capacity;
}
#Override
public void setCapacity(T capacity) {
this.capacity = capacity;
}
}
class PassengerVehicle<T> extends Vehicle<T> {
#Override
public T getCapacity() {
return capacity;
}
#Override
public void setCapacity(T capacity) {
this.capacity = capacity;
}
}
As you can see above the generic methods and you can use them as follow:
Vehicle<String> vehicleString = new TransportationVehicle<String>();
vehicleString.setCapacity("Seriously!"); //no problem
Vehicle<Integer> vehicleInteger = new PassengerVehicle<Integer>();
vehicleInteger.setCapacity(3); //boxing done automatically
Vehicle<Double> vehicleDouble = new PassengerVehicle<Double>();
vehicleDouble.setCapacity(2.2); //boxing done automatically
You can decide the type while coding and if you supply a Vehicle<String> with capacity as Integer then you will get compile time error, so you won't be allowed.
System.out.println(vehicleString.getCapacity());
//output: Seriously!
System.out.println(vehicleInteger.getCapacity());
//output: 3
System.out.println(vehicleDouble.getCapacity());
//output: 2.2
I don't understand the example. How do you realize that you are dealing with a concrete type in the first place? Are you instanceOf-ing? Are you type matching?
If so your problem is way past casting...
Anyways when you have objects that must belong to the same family and algorithms which are not abstract and change according to the object being handled you typically use some sort of behavioral pattern like visitor, or the Bridge pattern.

How to limit generic class parameter to certain classes

In my generic class I need to restrict type parameter to Integer OR String. Is there a way to achieve this? I cannot use T extends SomeClass to limit types, because common parent is just Object...
update
public abstract class MyClass<T>{
private T value;
public T getValue(){
return value;
}
}
I'd like the value type to be a String or an Integer and I need to use the same method to get it (not getIntValue() + getStringValue() )
This doesn't seem to help...
If I were you, I would overload two methods:
public void withInteger(Integer param) { .. }
public void withString(String param) { .. }
Note that there's no reason to use something like T extends String, because both String and Integer are final and can't be subclassed.
Just made your class ctor private and pass through a factory method to create implementation; type restriction is not bounded to MyClass but via factory.
class MyClass<T> {
private T value;
MyClass(T value) { this.value = value; }
public T getValue() { return value; }
}
class MyClassFactory {
public final static MyClass<Integer> createInteger(Integer i) {
return new MyClass<Integer>(i);
}
}

enum properties & side effects

I have a question regarding enum (it might be a simple one but ....).
This is my program:
public class Hello {
public enum MyEnum
{
ONE(1), TWO(2);
private int value;
private MyEnum(int value)
{
System.out.println("hello");
this.value = value;
}
public int getValue()
{
return value;
}
}
public static void main(String[] args)
{
MyEnum e = MyEnum.ONE;
}
}
and my question is: Why the output is
hello
hello
and not
hello
?
How the code is "going" twice to the constructor ?
When is the first time and when is the second ?
And why the enum constructor can not be public ?
Is it the reason why it print twice and not one time only ?
Enums are Singletons and they are instanciated upon loading of the class - so the two "hello"s come from instanciating MyEnum.ONE and MyEnum.TWO (just try printing value as well).
This is also the reason why the constuctor must not be public: the Enum guarantees there will ever only be one instance of each value - which it can't if someone else could fiddle with the constructor.
How the code is "going" twice to the constructor ?
Conctructor is invoked for each element of enum. Little change your example for demonstration it:
public class Hello {
public enum MyEnum {
ONE(1), TWO(2);
private int value;
private MyEnum(int value) {
this.value = value;
System.out.println("hello "+this.value);
}
public int getValue() {
return value;
}
}
public static void main(String[] args) {
MyEnum e = MyEnum.ONE;
}
}
Output:
hello 1
hello 2
Your constructor invoke twice. The moment of loading your Enum class it will invoke number of time which equals to number of enum types here.
MyEnum e = MyEnum.ONE; // singleton instance of Enum
consider following
public class Hello {
public enum MyEnum
{
ONE(1), TWO(2), THREE(3);
private int value;
private MyEnum(int value)
{
System.out.println("hello"+value);
this.value = value;
}
public int getValue()
{
return value;
}
}
public static void main(String[] args)
{
MyEnum e = MyEnum.ONE;
}
}
Out put
hello1
hello2
hello3

Categories

Resources