See code just bellow
Our generic interface
public interface Repository<INSTANCE_CLASS, INSTANCE_ID_CLASS> {
void add(INSTANCE_CLASS instance);
INSTANCE_CLASS getById(INSTANCE_ID_CLASS id);
}
And a single class
public class Order {
private Integer id;
private Integer orderNumber;
// getter's and setter's
public void equals(Object o) {
if(o == null)
return false;
if(!(o instanceof Order))
return false;
// business key
if(getOrderNumber() == null)
return false;
final Order other = (Order) o;
if(!(getOrderNumber().equals(other.getOrderNumber())))
return false;
return true;
}
// hashcode
}
And when i do the following test
private Repository<Order, Integer> repository;
#Before
public void setUp {
repository = EasyMock.createMock(Repository.class);
Order order = new Order();
order.setOrderNumber(new Integer(1));
repository.add(order);
EasyMock.expectLasCall().once();
EasyMock.replay(repository);
}
#Test
public void addOrder() {
Order order = new Order();
order.setOrderNumber(new Integer(1));
repository.add(order);
EasyMock.verify(repository)
}
I get
Unexpected method call add(br.com.smac.model.domain.Order#ac66b62):
add(br.com.smac.model.domain.Order#ac66b62): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:43)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:72)
at $Proxy4.add(Unknown Source)
Why does it not work as expected ??? What should i do to pass the test ??? Any workaround ???
I copied your code and ran it with Java 1.6 using EasyMock 2.0 and it works just fine. I had to fix some parts like public void equals(Object o) which should be public boolean equals, but it seems clear that you had it right in your real code.
Are you using another EasyMock version or do I miss something?
Cheers
Thomas
Related
i have a Device parent class like this
class Device{
int id;
public Device(int id);
}
and some child devices
class SwitchDevice extends Device{
boolean state;
public SwitchDevice(int id);
boolean getState();
void setState(boolean state);
}
class LightDevice extends SwitchDevice{
int value;
public SwitchDevice(int id);
int getValue();
void setValue(int value);
}
and then i have a Device handler which has a list of Device objects and some methods to retreive device instances from the list
class DeviceHandler {
private List<Device> deviceList;
public DeviceHandler() {
deviceList = new ArrayList<Device>();
}
public Device getById(int devId);
}
i want to know how can i call the childs methods from this list
what i mean is something like
Device dev = deviceHandler.getById(0);
boolean state = dev.getState;
i know that in java this is not possible, but maybe you can suggest me how to achieve de result.
i have tried the visitor pattern but in my case is not the right one because it doesn't allow me to return the value.
the only way seems to be adding in the handler class a method for each value of each device like this
boolean getSwitchState(Device dev){
if(dev.instanceOf(SwitchDevice)){
SwitchDevice device = (SwitchDevice)dev;
return device.getState();
}else{
throw new Exception();
}
but it needs a lot of code and is not safe.
I hope you understand what i mean (i'm not so good in english, and not an expert java programmer).
1. Use instanceof
You already use instanceof but I don't understand why need a lot of code here. It is safe.
Device dev = deviceHandler.getById(0);
if (dev instanceof SwitchDevice) {
((SwitchDevice)dev).getState()
}
// More check instanceof
2. Use Reflection
try {
// Get public getState()
Method m = dev.getClass().getMethod("getState");
Boolean state = (Boolean )m.invoke(dev);
} catch (NoSuchMethodException ex) {
// dev is not SwitchDevice
}
3. Add all common behaviors into Device base class (OR Interface?)
class Device{
// ...
public boolean getState() {
throw new UnsupportedOperationException();
}
public int getValue() {
throw new UnsupportedOperationException();
}
}
class SwitchDevice extends Device {
// ...
#Override
public boolean getState() {
return this.state;
}
}
class LightDevice extends SwitchDevice {
// ...
#Override
public int getValue() {
return this.value;
}
}
For this solution. You need to be aware of UnsupportedOperationException
If it is unavoidable to deal with casting at least do it in one place. Since the calling code already expects a particular subclass from getById method then update that method to be generic and do all the casting inside it:
public <T extends Device> Optional<T> getById(Class<T> deviceType, int devId){
Device d = deviceList.get(devId);
if ( d == null || !deviceType.isInstance(d) ) return Optional.empty();
return Optional.of( deviceType.cast(d) );
}
And then call it like this:
Optional<SwitchDevice> sd = deviceHandler.getById(SwitchDevice.class, 1);
boolean state = sd.orElseThrow( () -> new Exception() ).getState();
or one liner:
boolean state = deviceHandler.getById(SwitchDevice.class, 1)
.orElseThrow( () -> new Exception() )
.getState();
EDIT: Sample project available on github.
I'm using Neo4J (Rest graph database, hosted in grapheneDb) and Spring Data in our backend project.
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringCypherRestGraphDatabase">
I have a simple one-to-many relationship between two entities: User and Stay.
EDIT: I thought this wasn't relevant for the issue, but after seeing a similar problem in SDN4, I think I need to update the question (there is a basic #NodeEntity class, and both entities are extending this base class).
#NodeEntity
public abstract class BasicNodeEntity implements Serializable {
#GraphId
private Long nodeId;
}
public class User extends BasicNodeEntity {
#RelatedTo(type = "HAS_STAY", direction = Direction.OUTGOING)
Set<Stay> stays;
public void addStay(Stay stay) {
stays.add(stay);
}
}
public class Stay extends BasicNodeEntity {
#RelatedTo(type = "HAS_STAY", direction = Direction.INCOMING)
User user;
}
I'm unable to persist more than one stay. The first stay I add to the user is persisted correctly, but just the first one. The next stays added never persists, and I always retrieve the first one.
The method I use to create a new stay is:
#Autowired
Neo4jOperations template;
#Transactional
private void createStay(Stay stay, User user) throws Exception {
stay = template.save(stay);
user.addStay(stay);
template.save(user);
// If i evaluate user at this point, it contains both stays
// But if I retrieve the user from the repository, it just contains
// the first stay, the second one has not persisted.
}
EDIT: User modified is retrieved correctly through UserRepository.
public interface UserRepositoryCustom {}
public interface UserRepository extends GraphRepository<User>, UserRepositoryCustom {
User findById(String id);
}
User user = userRepository.findById(userId);
NOTE: I also tried to save through the repository interface instead of the Neo4jTemplate one, but I have the same problem.
Both entities are correctly saved in the neo4j database, it's just a persistence issue.
I think this should be quite easy, so I'm probably missing something..
Any help would be greatly appreciated.
Relevant versions:
<spring.version>4.0.5.RELEASE</spring.version>
<spring-data-neo4j.version>3.3.2.RELEASE</spring-data-neo4j.version>
There is another SO question with a very similar problem, but without response so far.
It is a tricky thing.
Your custom equals method causes two entities which have their node-id set but not yet their uuid-id set, to be equal so that when loading them into a set the set will only contain one.
Code in: RelationshipHelper
protected Set<Object> createEntitySetFromRelationshipEndNodes(Object entity, final MappingPolicy mappingPolicy, final Class<?> relatedType) {
final Iterable<Node> nodes = getStatesFromEntity(entity);
final Set<Object> result = new HashSet<Object>();
for (final Node otherNode : nodes) {
Object target = template.createEntityFromState(otherNode, relatedType, mappingPolicy);
result.add(target);
}
return result;
}
If you change your code to have an equals/hashcode in your BasicNode entity:
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BasicNodeEntity)) return false;
BasicNodeEntity that = (BasicNodeEntity) o;
if (nodeId != null) {
if (!nodeId.equals(that.nodeId)) return false;
} else {
if (that.nodeId != null) return false;
}
return true;
}
#Override
public int hashCode() {
return nodeId != null ? nodeId.hashCode() : 0;
}
so that entities that have only a nodeId set are comparable
and adapt the subclass methods
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof IdentifiableEntity)) return false;
IdentifiableEntity entity = (IdentifiableEntity) o;
//change
if (!super.equals(o)) return false;
if (id != null) {
if (!id.equals(entity.id)) return false;
} else {
if (entity.id != null) return false;
}
return true;
}
#Override
public int hashCode() {
//change
if (super.hashCode() != 0) return super.hashCode();
return id != null ? id.hashCode() : 0;
}
Then it works.
Going forward if you are working with Neo4j Server I recommend to you to check out SDN 4 RC2 instead which was released on Friday.
Normally when using Mockito I will do something like:
Mockito.when(myObject.myFunction(myParameter)).thenReturn(myResult);
Is it possible to do something along the lines of
myParameter.setProperty("value");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("myResult");
myParameter.setProperty("otherValue");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("otherResult");
So rather than when just using the parameter to determine the result. It is using a value of a property inside the parameter to determine the result.
So when the code is executed it behaves like so:
public void myTestMethod(MyParameter myParameter,MyObject myObject){
myParameter.setProperty("value");
System.out.println(myObject.myFunction(myParameter));// outputs myResult
myParameter.setProperty("otherValue");
System.out.println(myObject.myFunction(myParameter));// outputs otherResult
}
Here is the current solution, hopefully something better can be suggested.
private class MyObjectMatcher extends ArgumentMatcher<MyObject> {
private final String compareValue;
public ApplicationContextMatcher(String compareValue) {
this.compareValue= compareValue;
}
#Override
public boolean matches(Object argument) {
MyObject item= (MyObject) argument;
if(compareValue!= null){
if (item != null) {
return compareValue.equals(item.getMyParameter());
}
}else {
return item == null || item.getMyParameter() == null;
}
return false;
}
}
public void initMock(MyObject myObject){
MyObjectMatcher valueMatcher = new MyObjectMatcher("value");
MyObjectMatcher otherValueMatcher = new MyObjectMatcher("otherValue");
Mockito.when(myObject.myFunction(Matchers.argThat(valueMatcher))).thenReturn("myResult");
Mockito.when(myObject.myFunction(Matchers.argThat(otherValueMatcher))).thenReturn("otherResult");
}
In Java 8 it is even simpler than all of the above:
when(mockObject.myMethod(anyString()))
.thenAnswer(invocation ->
invocation.getArgumentAt(0, String.class));
Here's one way of doing it. This uses an Answer object to check the value of the property.
#RunWith(MockitoJUnitRunner.class)
public class MyTestClass {
private String theProperty;
#Mock private MyClass mockObject;
#Before
public void setUp() {
when(mockObject.myMethod(anyString())).thenAnswer(
new Answer<String>(){
#Override
public String answer(InvocationOnMock invocation){
if ("value".equals(theProperty)){
return "result";
}
else if("otherValue".equals(theProperty)) {
return "otherResult";
}
return theProperty;
}});
}
}
There's an alternative syntax, which I actually prefer, which will achieve exactly the same thing. Over to you which one of these you choose. This is just the setUp method - the rest of the test class should be the same as above.
#Before
public void setUp() {
doAnswer(new Answer<String>(){
#Override
public String answer(InvocationOnMock invocation){
if ("value".equals(theProperty)){
return "result";
}
else if("otherValue".equals(theProperty)) {
return "otherResult";
}
return theProperty;
}}).when(mockObject).myMethod(anyString());
}
Yes you can, using a custom argument matcher.
See the javadoc of Matchers for more details, and more specifically ArgumentMatcher.
Here is how it would look like in Kotlin with mockito-kotlin library.
mock<Resources> {
on {
mockObject.myMethod(any())
} doAnswer {
"Here is the value: ${it.arguments[0]}"
}
}
You can do this with Mockito 3.6.0:
when(mockObject.myMethod(anyString()))
.thenAnswer(invocation -> myStringMethod(invocation.getArgument(0)));
This answer is based on Sven's answer and Martijn Hiemstra's comment, with getArgumentAt() changed to getArgument().
I have written three program one using Generics and other one not used generics
Using isAssignableFrom
public class ObjectSpecificCondition {
private Class classType;
public boolean check(Object obj) {
boolean check = ((DateObject) obj).getLocalizationdate();
}
public ObjectSpecificCondition(Class classType) {
this.classType = classType;
}
boolean checkTypeSpecific(Object busineesObject) {
if (classType.isAssignableFrom(busineesObject.getClass())) {
return true;
}
else{
throw new Exception();
}
}
Using instanceOf
class ObjectSpecificCondition1 {
public boolean check(Object busineesObject) {
boolean check ;
if(busineesObject instanceof DateObject){
check= ((DateObject) busineesObject).getLocalizationdate();
}
else{
throw new IllegalArgumentException();
}
return check;
}
}
Using Generics
class ObjectSpecificConditionGenerics<T extends DateObject> {
private T classTypeGenerics;
public boolean check(T genericsobj) {
genericsobj.getLocalizationdate();
}
}
Business Object Rule
class DateObject {
boolean getLocalizationdate() {
// return true Or False according to business logic
}
}
Main test
public static void main(String[] args) throws Exception {
DateObject mockdateObject = new DateObject();
// caseI: No generics used caseI works fine no exception is generated but more lines of code to write
ObjectSpecificCondition mockanalysis = new ObjectSpecificCondition(DateObject.class);
if (mockanalysis.checkTypeSpecific(mockdateObject)) {
mockanalysis.check(mockdateObject);
}
// caseII:No generics used caseII throws exception in run time .More lines of code to write.It can not capture incompatible type at compile time
ObjectSpecificCondition mockanalysis1 = new ObjectSpecificCondition(String .class);
DateObject mockdateObject1 = new DateObject();
if (mockanalysis.checkTypeSpecific(mockdateObject1)) {
mockanalysis.check(mockdateObject1);
}
// caseIII;Generics used and line of code is reduced to less
ObjectSpecificConditionGenerics mockgenerics=new ObjectSpecificConditionGenerics() ;
mockgenerics.check(mockdateObject);
// caseIV;Generics used and line of code is reduced to less and error for compataible object is generated at compile time
ObjectSpecificConditionGenerics mockgenerics1=new ObjectSpecificConditionGenerics() ;
String mockstring=new String();
mockgenerics.check(mockstring); // it is captured at compile time ,i think its good to catch at compile time then to pass it at run time
}
}
I am seen in frameworks using three approaches .I want to get more confirm which one can be the best one?Using generics less line of code and at compile time error can be produced.But,another approach is also more used.I want to get more deeper answer .Any help please
The generic and non-generic versions should be the same, the only differences being the type parameters and casts. The non-generic version should be the type erasure of the generic version. Any generic code can be converted into equivalent non-generic code by applying the type erasure conversion.
Not Using Generics
public class ObjectSpecificCondition {
private Class classType;
public boolean check(DateObject obj) {
boolean check = obj.getLocalizationdate();
}
public ObjectSpecificCondition(Class classType) {
this.classType = classType;
}
boolean checkTypeSpecific(Object busineesObject) {
if (classType.isInstance(busineesObject)) {
return true;
}
else{
throw new Exception();
}
}
}
Using Generics
public class ObjectSpecificCondition<T extends DateObject> {
private Class<T> classType;
public boolean check(T obj) {
boolean check = obj.getLocalizationdate();
}
public ObjectSpecificCondition(Class<T> classType) {
this.classType = classType;
}
boolean checkTypeSpecific(Object busineesObject) {
if (classType.isInstance(busineesObject)) {
return true;
}
else{
throw new Exception();
}
}
}
I'm sorry if this question has been asked before, but I don't really know what to search for.
Anyway, I'm making a math package, and many of the classes extend Function:
package CustomMath;
#SuppressWarnings("rawtypes")
public abstract class Function <T extends Function> {
public abstract Function getDerivative();
public abstract String toString();
public abstract Function simplify();
public abstract boolean equals(T comparison);
}
I want to compare functions to see if they're equal. If they're from the same class, I want to use its specific compare method, but if they're of different classes, I want to return false. Here is one of the classes I have currently:
package CustomMath;
public class Product extends Function <Product> {
public Function multiplicand1;
public Function multiplicand2;
public Product(Function multiplicand1, Function multiplicand2)
{
this.multiplicand1 = multiplicand1;
this.multiplicand2 = multiplicand2;
}
public Function getDerivative() {
return new Sum(new Product(multiplicand1, multiplicand2.getDerivative()), new Product(multiplicand2, multiplicand1.getDerivative()));
}
public String toString() {
if(multiplicand1.equals(new RationalLong(-1, 1)))
return String.format("-(%s)", multiplicand2.toString());
return String.format("(%s)*(%s)", multiplicand1.toString(), multiplicand2.toString());
}
public Function simplify() {
multiplicand1 = multiplicand1.simplify();
multiplicand2 = multiplicand2.simplify();
if(multiplicand1.equals(new One()))
return multiplicand2;
if(multiplicand2.equals(new One()))
return multiplicand1;
if(multiplicand1.equals(new Zero()) || multiplicand2.equals(new Zero()))
return new Zero();
if(multiplicand2.equals(new RationalLong(-1, 1))) //if one of the multiplicands is -1, make it first, so that we can print "-" instead of "-1"
{
if(!multiplicand1.equals(new RationalLong(-1, 1))) // if they're both -1, don't bother switching
{
Function temp = multiplicand1;
multiplicand1 = multiplicand2;
multiplicand2 = temp;
}
}
return this;
}
public boolean equals(Product comparison) {
if((multiplicand1.equals(comparison.multiplicand1) && multiplicand2.equals(comparison.multiplicand2)) ||
(multiplicand1.equals(comparison.multiplicand2) && multiplicand2.equals(comparison.multiplicand1)))
return true;
return false;
}
}
How can I do this?
With generic you have the guarantee that the equals method is only apply with the type 'T', in this case 'Product'. You can't passe another class type.
Another possibility would be in classe Function define:
public abstract boolean equals(Function comparison);
And in classe Product the object comparison whith a comparison instanceof Product
Override Object.equals(Object) method. You don't need to use generics here. Its body will look something like this
if (other instanceof Product) {
Product product = (Product) other;
// Do your magic here
}
return false;