How can I get the default value of a parameter (method) in groovy at runtime? - groovy

How can I get the default value of a parameter (method) in groovy at runtime?
Is there a possibility?

How can I get the default value of a parameter (method) in groovy at
runtime? Is there a possibility?
Aside from invoking the method without supplying the parameter and then inspecting the value that was passed in, not a practical one, no. You could write code that parses the .class file and the info is there, but I don't think there is anything in Groovy related that is going to help or be relevant.

Related

SOAPUI context variables - How does Groovy make this possible?

Sorry to all you Groovy dudes if this is a bit of a noob question.
In SOAPUI, i can create a Groovy script where i can define an arbitrary variable to the run context to retrieve at a later time.
context.previouslyUndefinedVariable = 3
def num = context.previouslyUndefinedVariable
What feature of Groovy allows previously undefined variables to be added to an object like this? I would like to learn more about it.
Many thanks in advance!
Groovy has the ability to dynamically add methods to a class through metaprogramming.
To learn more, see:
What is Groovy's MetaClass used for?
Groovy Goodness: Add Methods Dynamically to Classes with ExpandoMetaClass
Runtime and compile-time metaprogramming
The accepted answer is a bit of a poor explanation for how SoapUI is doing it.
In this case, context is always an instance of some SoapUI library java class (such as WsdlTestRunContext), and these are all implementations of Map. You can check context.getClass() and assert context in Map.
When you look up a property on a Map, Groovy uses the getAt and putAt methods. There are various syntaxes you can use. All of these are equivalent:
context.someUndef
context.'someUndef'
context[someUndef]
context['someUndef']
context.getAt('someUndef')
And
context.someUndef = 3
context.'someUndef' = 3
context[someUndef] = 3
context['someUndef'] = 3
context.putAt('someUndef', 3)
I like to use any of the above that include quote marks, so that Groovy-Eclipse doesn't flag it as a missing property.
It's also interesting that Groovy looks for a getAt() method before it checks for a get method being referred to as a property.
For example, consider evaluating "foo".class. The String instance doesn't have a property called class and it also doesn't have a method getAt(String), so the next thing it tries is to look for a "get" method with that name, i.e. getClass(), which it finds, and we get our result: String.
But with a map, ['class':'bar'].class refers to the method call getAt('class') first, which will be 'bar'. If we want to know what type of Map it is, we have to be more specific and write in full: ['class':'bar'].getClass() which will be LinkedHashMap.
We still have to specify getClass() even if that Map doesn't have a matching key, because ['foo':'bar'].class will still mean ['foo':'bar'].getAt('class'), which will be null.

How to match a possible null parameter in Mockito

I'm trying to verify that the class I'm testing calls the correct dependency class's method. So I'm trying to match the method parameters, but I don't really care about the actual values in this test, because I don't want to make my test brittle.
However, I'm running into trouble setting it up because Mockito has decided that the behaviour I'm expecting is a bug: https://github.com/mockito/mockito/issues/134
So what't the correct way to define an ArgumentMatcher for a parameter that might be null?
With issue #134 "fixed", this code fails because the matchers only match in the first case. How can I define a matcher to work in all 4 cases?
MyClass c = mock(MyClass.class);
c.foo("hello", "world");
c.foo("hello", null);
c.foo(null, "world");
c.foo(null, null);
verify(c, times(4)).foo(anyString(), anyString());
From the javadocs of any()
Since Mockito 2.1.0, only allow non-null String. As this
is a nullable reference, the suggested API to match
null wrapper would be isNull(). We felt this
change would make tests harness much safer that it was with Mockito
1.x.
So, the way to match nullable string arguments is explicit declaration:
nullable(String.class)
I got this to work by switching to any(String.class)
I find this a bit misleading, because the API seems to suggest that anyString() is just an alias for any(String.class) at least up till the 2.0 update. To be fair, the documentation does specify that anyString() only matches non-null strings. It just seems counter-intuitive to me.
How about:
verify(c, times(4)).foo(anyObject(), anyObject());
Does that work for you?
Matchers.anyObject() allows for nulls.
Reference in Mockito docs:

Groovy - Type Check Closure Code Before Execution

I have a Groovy script that lets the user define some dynamic properties and methods and later executes a user-defined closure. A script would look like this:
// init properties and methods dynamically at runtime
context.prop1 = "Some test value"
context.method1 = { String input ->
"exec " + input.toUpperCase()
}
// "this" is set to the context variable from above
run {
println method1( prop1 )
}
So in the beginning of the script, a context is initialized with user-defined properties (e.g. prop1) and methods (e.g. method1). The context is then used as this pointer in the run closure. I have achieved this by dynamically extending the meta class of the context and setting the context as delegate of the run closure (with DELEGATE_FIRST as resolves strategy).
Currently I am struggling at type checking. Before executing the run closure, I would like to check if method1 really expects prop1. I have looked into the DelegatesTo annotation, but that doesn't seem to work for dynamically extended objects. I have also played with the AST, but since my knowledge on that topic is limited, I haven't come up with a solution. If what I want to achieve is possible, any pointers in the right direction would be greatly appreciated.
You want to add a method to a context at runtime and then type check this before execution of that method.
Type checking is done at compile time. That is before anything of your program is executed. There is normally no chance this can ever check anything that will only happen at runtime, unless you have a way to statically declare it and give the compiler the power to do the check. But this means normally, you will have to do static compilation.
One way would be to use type checking extensions, but I think in your case that might be overkill. A more simple way would be to use extension modules. And the most simple way would be to use custom script base class.
But for any of these solution you will need static compilation to really have type checking, same for DelegatesTo (which is more used in combination with extension modules). For a type checked DSL a mix of type checking extensions and extension modules can work very well. But you will of course loose more dynamic features of the language and some simplicity.

Groovy - Correct way to implement getProperty method

I need to run some code whenever a property value is retrieved, so naturally it made sense to define the getProperty method in my class. This method will get automatically called whenever a property value is retrieved. Here's roughly what I have in my class:
class MyClass
{
def getProperty(String name)
{
// Run some code ...
return this.#"${name}"
}
}
The problem with the above method occurs when someone tries to make the following call somewhere:
MyClass.class
This call ends up in the getProperty method looking for a property named "class", however, there is not actual property named "class" so we get a MissingFieldException.
What would be the correct way to implement running code whenever a property value is retrieved and deal with these kind of situtations.
Best is not to have a getProperty method if not needed. If you need one and you want to fall back on standard Groovy logic, then you can use return getMetaClass().getProperty(this, property), as can be found in GroovyObjectSupport. This will cover more than just fields.
This seems to be a common problem with this method. Map has the same issue. The developers of groovy got around the problem with Map by saying you need to use getClass() directly.

testing for empty groovy closure?

I want to let users supply a groovy class with a property that is a file-selector closure which I pass on to AntBuilder's 'copy' task:
class Foo {
def ANT = { fileset(dir:'/tmp/tmp1') }
}
in my code, I pick up the ANT property as 'fAnt' and pass to Ant:
ant.copy(todir:'/tmp/tmp2', fAnt)
This works - but, if the user passes in an empty closure (def ANT={}) or with a selector that doesn't select anything (maybe the fileset dir doesn't exist) then it blows up. I tried surrounding the ant copy with a try-catch to catch the InvokerInvocationException, but somehow the exception comes through anyway ... while I'm tracking that down, is there a way to read back a groovy Closure's contents as a string, or to test if it's empty?
In short: No. You can't decompile a closure in a meanngful way at runtime. If it's user supplied, the Closure could even be a Java class.
Long answer: If you want to do a lot of work, you might be able to, but it's probably not worth it. The Groovy parser is part of the API, so if you have access to the source, you can theoretically examine the AST and determine if the closure is empty. Look into the SourceUnit class.
It's almost certainly not worth the effort though. You're better off catching the exception and adding a helpful message like "You may have passed an empty closure or invalid fileset".
One mystery solved - the exception I need to catch is org.apache.tools.ant.BuildException - so I can just catch that to trap errors, but the original question remains - is there a way to examine a Closure's contents?

Resources