Java 1.8 overridden equals() not called by Collection removeAll() - collections

on my IDE (eclipse neon) i m running jre 1.8. As you can see in the snippet code below i developed My Custom class overriding the equals method. That s cause i want to use my overridden version when i execute the removeAll method from a Set of my custom class.
Looking inside the jdk source code it's possible to verify that removeAll method uses the contains method which in turn uses the equals method of the Object class.
public class MyClass {
private String connectionID;
public MyClass (){
...
}
#Override
public boolean equals(Object obj) {
if (obj instanceof MyClass ){
if (((MyClass )obj).getConnectionID().equalsIgnoreCase(this.getConnectionID())){
return true;
}
}
return false;
}
...
}
public class MyClassContainer{
private Set<MyClass> classes = new HashSet<>();
public Set<MyClass> getClasses () {
return this.classes ;
}
}
public class Main (){
private void method(MyClassContainer contClass) {
if (true){
Set<MyClass> temp = some valid Set;
temp.removeAll(contClass.getClasses());
}
}
Launching this code i m realizing that the overridden equals method is never called.
What is it wrong?
Thanks

For it to work correctly, you need to override hashCode as well:
#Override
public int hashCode() {
return Objects.hash(getConnectionID());
}

Related

Custom ConstraintValidator unit test using Quarkus

I need to make validations on my custom ConstraintValidator that uses an #Inject needed for some validations, it's like this example from quarkus https://quarkus.io/guides/validation
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
#Inject
MyService service;
#Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return service.validate(value);
}
}
When i run the application I see that is made the right validation, but i'm trying to make unit test using mockito i can't mock the object is always null on the default using the Default Bean validation.
On the example from quarkus is unit test only for integration.
this is my implementation
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
#Inject
BookService service;
#ConfigProperty(name = "my.property")
int myLimit;
public MyConstraintValidator(BookService service) {
this.service = service;
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context) {
System.out.println("myLimit property: " + myLimit);
int limit = Integer.parseInt(value);
if (limit < myLimit) {
return service.validate(value);
} else {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(NAME_EMPTY).addConstraintViolation();
return false;
}
}
}
Unit test for testing the custom Validator
#Test
void testAmountValidationWithContext() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("11");
//when:
myConstraintValidator = new MyConstraintValidator(service);
Mockito.when(service.validate(anyString())).thenReturn(true);
//then:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
// verify that the context is called with the correct argument
Mockito.verify(context).buildConstraintViolationWithTemplate(NAME_EMPTY);
}
The unit test to test the default #NoBlank.
#Test
void testBeanValidationWithInvalidAmount() {
BookRequest bookRequest = new BookRequest();
bookRequest.setTitle("my title");
bookRequest.setAuthor("my Author");
bookRequest.setPages(2L);
bookRequest.setAmount("AA");
//when:
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);
//then:
assertEquals(1, violations.size());
assertEquals(NOT_EMPTY, violations.stream().findFirst().get().getMessage());
}
The first unit test works weel, i can mock the object and test the result.
The problem is on my second test, when i try to test the other validations #NotNull, #Pattern. On this test the method isValid() is also invoked and here it's my problem because the #ConfigProperty and the #Inject are always null, and i can't mocked them.
I already saw several examples over internet but doesn't work and are almost for spring but i need to make the custom validation on quarkus.
How can i implement the custom ConstraintValidator unit test using quarkus?
Does any one have any example with this working?
Changing your code from field injection to constructor injection will make unit testing much easier.
#ApplicationScoped
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
private final MyService service;
private final int myLimit;
public MyConstraintValidator(MyService service, #ConfigProperty(name = "my.property") int myLimit) {
this.service = service;
this.myLimit = myLimit;
}
#Override
public boolean isValid(String value, ConstraintValidatorContext context)
{
if (value == null) {
return true;
}
return service.validate(value);
}
}
Updated description with my implementations.
but resuming the issue.
when i have the default annotations with my custom validator i can't mock the objects using the
Set<ConstraintViolation<BookRequest>> violations = validator.validate(bookRequest);

PowerMockito failing to create an instance of a class which has anonymous block

I just converted our application code into simple classes to express the problem concisely. Our use case contains a class which internally uses some helper classes with static methods which needs to be mocked. So, planned to use PowerMockito. No issues with this part, however we have one class where we have an anonymous block inside one of the methods. When we try to create an instance of this class, PowerMockito fails with a very vague error. Tried spending few hours to resolve the issue without any luck.
public abstract class AbstractClass {
public abstract void methodOne(String arg);
public void methodTwo()
{
System.out.println("In method two");
}
}
public class StaticMethod {
public static String someStaticMethod()
{
System.out.println("in static method");
return "static";
}
}
public class AbstractClassCaller {
public AbstractClassCaller()
{
StaticMethod.someStaticMethod();
// The following piece of code is the problematic block
AbstractClass abstractClassInstance = new AbstractClass(){
public void methodOne(String methodArg)
{
System.out.println("In Method One");
}
};
}
}
#Test
#PrepareForTest({AbstractClassCaller.class,StaticMethod.class})
public class AbstractClassCallerTest {
#Test
public void test() throws Exception
{
PowerMockito.mockStatic(StaticMethod.class);
PowerMockito.when(StaticMethod.someStaticMethod()).thenReturn(
"PowerStatic");
// This is the code which triggers the exception
AbstractClassCaller instance = new AbstractClassCaller();
}
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
The above junit class fails with the following exception:
org.powermock.reflect.exceptions.ConstructorNotFoundException: Failed to lookup constructor with parameter types [ com.oracle.oal.seaas.AbstractClassCaller ] in class com.oracle.oal.seaas.AbstractClassCaller$1.
at com.oracle.oal.seaas.AbstractClassCallerTest.test(AbstractClassCallerTest.java:21)
Caused by: java.lang.NoSuchMethodException: com.oracle.oal.seaas.AbstractClassCaller$1.<init>(com.oracle.oal.seaas.AbstractClassCaller)
at com.oracle.oal.seaas.AbstractClassCallerTest.test(AbstractClassCallerTest.java:21)
// the following anonymous block in AbstractClassCaller is causing the issue:
AbstractClass abstractClassInstance = new AbstractClass(){
public void methodOne(String methodArg)
{
System.out.println("In Method One");
}
};
Any ideas on how to fix this issue?

Javafx and the Observer pattern - updating a UI

I am trying to implement the Observer pattern in a JavaFx application. I've never asked a question here but this is driving me a bit crazy.
Essentially I'm trying to use the Observer pattern to monitor a class that's parsing a file of phone numbers, and update the UI automatically as the file is parsed.
Before I get to my questions, here is my code:
Abstract class Observer.java
public abstract class Observer
{
public PhoneBook numbers;
public abstract void update();
}
I have a class that implements this:
public class PhoneBookObserver extends Observer {
public PhoneBookObserver(PhoneBook numbers)
{
this.numbers = numbers;
this.numbers.attach(this);
}
#Override
public void update()
{
System.out.println(""NUMBER - : " + numbers.GetNumbers());
}
}
In the class doing the parsing, I've created a new PhoneBookObserver
public PhoneBook ParsePhoneBook()
{
PhoneBook nums= new PhoneBook();
PhoneBookObserver p = new PhoneBookObserver(nums);
// ... Parsing of file - works fine
return nums;
}
Currently this runs and my println from update() in PhoneBookObserver is output.
My questions are:
Can the update method of PhoneBookObserver update my UI for me? How would it access JavaFx elements in my controller?
Can I just make my controller an observer, override update() and use that to update my UI elements from within my controller? Is that bad?
To directly answer your question, I would probably implement the Observer as an inner class in the controller. Then it has access to everything in the controller.
Assuming here PhoneBook defines a method of the form
public List<PhoneNumber> getPhoneNumbers() ;
then you could do:
public class Controller {
#FXML
private ListView<PhoneNumber> phoneNumberList ;
private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere
public void initialize() {
numbers.attach(new PhoneBookObserver(numbers));
// ...
}
private class PhoneBookObserver extends Observer {
PhoneBookObserver(PhoneBook numbers) {
this.numbers = numbers ;
}
#Override
public void update() {
phoneNumberList.getItems().setAll(numbers.getPhoneNumbers());
}
}
}
Note that in
public abstract class Observer
{
public PhoneBook numbers;
public abstract void update();
}
the field numbers really serves no purpose, as the only method doesn't use it. So you could remove it (subclasses can define such a field if they need). Then you may as well make it an interface, and since it only has one method, it's a #FunctionalInterface:
#FunctionalInterface
public interface Observer {
public void update() ;
}
and now it can be implemented with a lambda expression, so the implementation is so thin that you basically stop having any issues with "accessing the UI":
public class Controller {
#FXML
private ListView<PhoneNumber> phoneNumberList ;
private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere
public void initialize() {
numbers.attach(() -> phoneNumberList.getItems().setAll(numbers.getPhoneNumbers());
// ...
}
}
Finally, note that JavaFX Properties and observable lists basically already provide an implementation of the observer pattern, so you're pretty much reinventing the wheel here. You could just have
public class PhoneBook {
private final ObservableList<PhoneNumber> numbers;
public ObservableList<PhoneNumber> getPhoneNumbers() {
return numbers ;
}
}
and then
public class Controller {
#FXML
private ListView<PhoneNumber> phoneNumberList ;
private PhoneBook numbers = new PhoneBook() ; // or initialize from elsewhere
public void initialize() {
phoneNumberList.setItems(numbers.getPhoneNumbers());
}
}
and the list view will observe the (already-observable) list of numbers for you. There is no real need for your Observer or PhoneBookObserver.

JMock map expectations

I have a dependency with a method that takes a Map as an argument.
public interface Service {
void doSomething(Map<String, String> map);
}
I'd like to write an assertion that this dependency is called with appropriate map contents. Something like this:
#RunWith(JMock.class)
public class MainTest {
private Mockery context = new Mockery();
private Service service = context.mock(Service.class);
private Main main = new Main(service);
#Test
public void test() {
context.checking(new Expectations(){{
oneOf(service).doSomething(with(hasEntry("test", "test")));
}});
main.run();
}
}
Unfortunately, this fails to compile, since hasEntry has wildcards in map generic parameters:
public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K, ? extends V>> hasEntry(K key, V value);
Is there any way to write a JMock expectaion for map contents?
There isn't a good answer to this as we hit the limits of Java generics. There's a tension between the generics we need for jMock and what we need for assertThat()
I tend to add a helper method, with an expressive name, to force the types.
#Test public void test() {
context.checking(new Expectations(){{
oneOf(service).doSomething(with(mapIncluding("test", "test")));
}});
main.run();
}
#SuppressWarnings({"unchecked", "rawtypes"})
private Matcher<Map<String, String>> mapIncluding(String key, String value) {
return (Matcher)Matchers.hasEntry(key, value);
};
Yes, this is pig-ugly. I can only apologise that this is the best we appear to be able to do. That said, it's rare that I have to go as far as turning off the types, I can give it a name that's meaningful in the domain, and I've localised the unchecking to the helper method.
I ended up creating a method specify() that allows downcasting of generic matchers to more specific ones
public static <T> Matcher<T> specify(final Matcher<? super T> matcher) {
return new TypeSafeMatcher<T>() {
#Override
protected boolean matchesSafely(T item) {
return matcher.matches(item);
}
#Override
public void describeTo(Description description) {
matcher.describeTo(description);
}
};
}
Using this method I can downcast any existing generic matcher, like hasEntry()
public <K, V> Matcher<Map<? extends K, ? extends V>> hasEntry(K key, V value)
to a more specific one in a generic-safe manner, like this:
private static <K,V> Matcher<Map<K, V>> aMapHavingEntry(K key, V value) {
return specify(hasEntry(key, value));
}
Now I can use this specific matcher as an expectation parameter:
context.checking(new Expectations() {{
oneOf(service).doSomething(with(aMapHavingEntry("test", "test")));
}});
Using specify() method I created a bunch of specific matchers for most popular interfaces: Map, Collection, List, Set, like:
private static <K,V> Matcher<Map<K, V>> aMapHavingEntry(K key, V value) {
return specify(hasEntry(key, value));
}
private static <K> Matcher<Collection<K>> aCollectionContainingInAnyOrder(K... items) {
return specify(containsInAnyOrder(items));
}
I also suggested adding the same functionality to JMock, though all I got was silence.

Mocking a protected generic method with Moq

To mock a protected virtual (non-generic) method in Moq is easy:
public class MyClass
{
....
protected virtual int MyMethod(Data data){..}
}
And to mock it:
myMock.Protected().Setup<int>("MyMethod", ItExpr.Is<Data>( ...
I could not find a way to use the same technique if the protected method is generic, like:
protected virtual int MyMethod<T>(T data)
Any idea how to do it, besides using a wrapper class to override that method, is highly appreciated.
I've checked the source and it seems mocking protected generic methods with Moq is not supported:
The Protected() method creates an instance of a class ProtectedMock<T> which uses the following method to get the method that you want to mock:
private static MethodInfo GetMethod(string methodName, params object[] args)
{
return typeof(T).GetMethod(
methodName,
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
null,
ToArgTypes(args),
null);
}
It uses Type.GetMethod to get the method for mocking, but GetMethod (although MSDN states differently) don't play nice with generics, see:
GetMethod for generic method
Get a generic method without using GetMethods
Side note:
In my opinion mocking a protected member is a code smell, and I would rather try to avoid it anyway with refactoring my design (beside that it's not supported in Moq).
It can be done since Moq 4.13 (2019-09-01) by using As for protected methods and It.IsAnyType for generic type arguments:
classUnderTest.Protected().As<IMyMethodMock>().Setup(x => x.MyMethod(It.IsAny<It.IsAnyType>())).Returns(...);
And create the following interface for the mocking method:
public interface IMyMethodMock
{
int MyMethod<T>(T data);
}
Full example:
[TestClass]
public class MockingProtectedGenericFixture
{
[TestMethod]
public void test()
{
// Arrange
var classUnderTest = new Mock<MyClass>();
classUnderTest.Protected().As<IMyMethodMock>().Setup(x => x.MyMethod(It.IsAny<It.IsAnyType>())).Returns(2);
// Act
var resForStringData = classUnderTest.Object.GetNumber("DataString");
var resForBooleanData = classUnderTest.Object.GetNumber(true);
// Assert
Assert.AreEqual(2, resForStringData);
Assert.AreEqual(2, resForBooleanData);
}
}
public class MyClass
{
public int GetNumber<T>(T data)
{
return MyMethod(data);
}
protected virtual int MyMethod<T>(T data)
{
return 1;
}
}
public interface IMyMethodMock
{
int MyMethod<T>(T data);
}

Resources