groovy singleton to access overloaded constructor - groovy

groovy Singleton (NB at Groovy 2.6 you must set strict to false if you want to include the explicit constructor)
#Singleton( strict = false )
class test {
private test(){
//some Method call
}
private test(def x){
//some Method call
}
}
test.groovy
def test1 = test.instance
when i issue the following statement it works for me and i can see the defualt
constructor is called
how can i create instanace while using second construcor argument
if i issue
def test2 = test("anish").instance
it throws me error how do i resolve this any suggestion
groovy.lang.MissingMethodException: No signature of method: test.test() is applicable for argument types: (java.lang.String) values: [anish]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:44)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:143)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:151)

In the first case you are accessing the static property test.instance, which in turn calls the static method test.getInstance(). In the second case, it looks like you are trying to call the second constructor as a method. That's not valid groovy: you need to use the new keyword to create an instance, which triggers the constructor. Also, making the constructor private makes it inaccessible except within the class itself.
If you need to instantiate another instance, it probably shouldn't be a singleton in the first place.

Related

Mocking a public method that has a private method call inside using Mockito (not Powermockito)

I am testing for methodA() in the class :
class Test{
public String methodA(String str){
...
methodB("s1","s2");
...
}
private String methodB(String s1, String s2){
...
}
}
What I have tried in my test class:
Method methodBReflect = Test.class.getDeclaredMethod("methodB", Test.class,String.class, String.class);
methodBReflect.setAccessible(true);
Test testForSpy=new Test();
Test spyTest=spy(testForSpy);
doReturn("return string").when(spyTest..)... // <-- What should be done here?
//methodBReflect.invoke(spyTest, "args1","args2");
P.S: I don't need a solution using powermock as I have some organizational constraints using it.
You shouldn't be testing that method A calls method B. You should test that method A does what method A is supposed to do - that is, it gives the correct output for whatever input you give it. Your test shouldn't care whether method A works by calling method B, or by doing all its processing inline.
Therefore, there's no need to mock or stub anything. Your tests will consist of a bunch of calls to method A, along with verification that the output is what you expect.
You only need to use Mockito (or some other mocking framework) when you're testing a class that interacts with another class entirely; not when the class under test interacts with itself.

Getting InvalidUseOfMatchersException in the Mockito

I have written this java method:
public int run(String jobName) {
}
And I have written this test code:
#Test
public void testBatchStatusUpdateWithOneCompleteStatus() {
Set<BatchEntity> staleBatch = createStaleBatch();
Set<Integer> activeBatch = createActiveBatch();
when(batchRepository.findBatchIdByStateIn(
(Arrays.asList(BatchStates.IN_PROGRESS,
BatchStates.INTENT_MARKED)))).thenReturn(staleBatch);
when(listingRepository.findBatchId()).thenReturn(activeBatch);
Assert.assertEquals(batchStatusUpdate.run(Mockito.any(String.class)), 1);
Mockito.verify(batchRepository,Mockito.times(2)).save(Mockito.any(BatchEntity.class));
}
I am getting the below error when I run the
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers! 0 matchers expected, 1 recorded: at backgroundjob.BatchStatusUpdateTest.testBatchStatusUpdateWithOneCompleteStatus This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String"); When using matchers, all arguments have to be provided by matchers. For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
I am getting this error when run method has the string argument. When I remove the string argument from the run method the test case is passed.
Mockito.any() creates a matcher, which is used when specifying a mock or when verifying calls with Mockito.verify(). They do not make sense as an argument to the method you are testing though. Your call should be changed to use an actual string, for example Assert.assertEquals(batchStatusUpdate.run("some value"), 1); instead of Assert.assertEquals(batchStatusUpdate.run(Mockito.any(String.class)), 1);

Access methods defined in another groovy script

I have two groovy scripts A and B.
A looks like:
import some.Class
//Some helper function
String doSomeWork(Integer input) {
//does something with input and returns a String
return "result: $input"
}
//Now do some real stuff here
println( doSomeWork(42) )
In B I want to import A (its in the classpath) and use its doSomeWork:
import A
println A //prints class A. This means we can access it here. =)
println( A.doSomeWork(45) ) //Now try to call As doSomeWork
The last line however results in an exception:
Caught: groovy.lang.MissingMethodException: No signature of method: static A.doSomeWork() is applicable for argument types: (java.lang.Integer) values: [45]
Possible solutions: doSomeWork(java.lang.Integer)
groovy.lang.MissingMethodException: No signature of method: static A.doSomeWork() is applicable for argument types: (java.lang.Integer) values: [45]
Possible solutions: doSomeWork(java.lang.Integer)
at B.run(B.groovy:3)
import A //Will execute As code
println A //prints class A. This means we can access it here. =)
println( (new A()).doSomeWork(45) ) //Now call As doSomeWork
What do I have to do to successfull call As doSomeWork in script B?
EDIT: Okay, I found out. it is not a static method but a method of A. So (new A()).doSomeWork(45) is doing the job. However, that means when A is imported, all its code is executed before Bs code. How can I avoid that? My goal is to only use As method (which obvioulsy does not access any of As properties) without A doing any other side effects.

Mock static method with no parameters in Groovy

I need to mock a static method. I'm using the EMC approach described at Mocking static methods using groovy. Like this
TestDaemon.metaClass.'static'.newDownloadManager = {downloadManager}
The method newDownloadManager has no parameters and for some reason it is not replaced. The original code is called. In debug mode I can see that the closure that I define has a parameter. May be that's the reason? How can I define a closure without parameters? Or how can I mock a static method with no parameters?
Meta class changes aren't visible to Java code. Groovy can't help you to mock a static method that gets called from Java code. You will have to use something like JMockit instead (or refactor the code under test).
A closure written like that has an implicit parameter. Write the closure with { -> } syntax. Example:
x = { println "foo" }
y = { -> println "foo" }
assert x.parameterTypes as List == [Object]
assert y.parameterTypes as List == []

How can I intercept execution of all the methods in a Java application using Groovy?

Is it possible to intercept all the methods called in a application? I'd like to do something with them, and then let them execute. I tried to override this behaviour in Object.metaClass.invokeMethod, but it doesn't seem to work.
Is this doable?
Have you looked at Groovy AOP? There's very little documentation, but it allows you to define pointcuts and advice in a conceptually similar way as for AspectJ. Have a look at the unit tests for some more examples
The example below will match all calls to all woven types and apply the advice before proceeding:
// aspect MyAspect
class MyAspect {
static aspect = {
//match all calls to all calls to all types in all packages
def pc = pcall("*.*.*")
//apply around advice to the matched calls
around(pc) { ctx ->
println ctx.args[0]
println ctx.args.length
return proceed(ctx.args)
}
}
}
// class T
class T {
def test() {
println "hello"
}
}
// Script starts here
weave MyAspect.class
new T().test()
unweave MyAspect.class
First of all, overriding Object.metaClass.invokeMethod doesn't work because when Groovy tries to resolve a method call for a type X, it checks the metaClass of X, but not the metaClass of its parent class(es). For example, the following code will print "method intValue intercepted"
Integer.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Integer.metaClass = null
But this code will not:
Object.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Object.metaClass = null
Your question was "Is it possible to intercept all the methods called in a application?", but could you be a bit more precise about whether you want to:
Intercept calls to Groovy methods, Java methods, or both
Intercept calls to only your Groovy/Java methods or also intercept calls to Groovy/Java library classes
For example, if you only want to intercept calls to your Groovy classes, you could change your classes to implement GroovyInterceptable. This ensures that invokeMethod() is invoked for every method called on those classes. If the nature of the interception (i.e. the stuff you want to do before/after invoking the called method) is the same for all classes, you could define invokeMethod() in a separate class and use #Mixin to apply it to all your classes.
Alternatively, if you also want to intercept calls to Java classes, you should check out the DelegatingMetaClass.

Resources