Thursday, December 27, 2018

MavenLocal

Take this scenario.

You are writing a new application A
B is an existing application that needs to be integrated with A

Now A is not in production yet and definitely not uploaded to your firm's Maven repository.
Or you might want to see how A works with B. Some basic integration, that I, as A's developer, need to ensure.

What I need is, to publish A in a local repository from where B will read from.

A and B both are gradle projects.

From A :


    publishing {
        repositories {
            mavenLocal()
        }
       
        publications {
            mavenJava(MavenPublication) {
                from components.java
            }
        }
    }


This uploads A's artifacts to m2 repository

And at B:



repositories {
        maven {
            url 'http://mavenAtMyFirm'
        }
        // Added to look for dependent libraries in local maven repo. Helps in integration
        mavenLocal()
    }


mavenLocal will read dependencies from local m2 repository.


Java 8 : Collectors.toMap | Do you know that Values cannot be null?

In Java Map, you can have null key and null values as well.

But when you are using Collectors.toMap() be wary not to have a KeyMapper and ValueMapper that will give null keys or null values.

Internally it uses Map.merge which will throw NPE if key or value is null. This is an open bug at JDK


Reference :
https://stackoverflow.com/questions/24630963/java-8-nullpointerexception-in-collectors-tomap 

Saturday, February 10, 2018

Mockito : Argument Captor - catches reference and not value

This is the service to test :

public void method(List<String> inputs) {

   Map<String,Object> parameterMap = new HashMap<>();

   parameterMap.put("common_attr1","blah");
   parameterMap.put("common_attr2","blah");

   for(String input: inputs) {
       parameterMap.put("selector",input);
       dao.makeDBCall(parameterMap);
   }

}

To collect the argument passed to the DB call, you would ideally go for the ArgumentCaptor and see if each call is made with the corresponding input passed to the method()


But, this will not work because ArgumentCaptor gives you the reference. so all the captured value will point to the argument corresponding to the last call made to the DB call.

Solution :

Use thenAnswer to collect the parameters while invoking the DB call.

List<String> actualSelectorsPassedForInputs = new ArrayList<>();
when(dao.makeDBCall(anyObject())).thenAnswer(invocation->{
 Object[] args = invocation.getArguments();
 HashMap<String,Object> parameterMap = (HashMap<String,Object>) args[0];
 actualSelectorsPassedForInputs.add(parameterMap.get("selector"));
});

// do assertions on actualSelectorsPassedForInputs

Reference :
1) https://stackoverflow.com/questions/11984128/capturing-previous-values-to-verify-mock-object