Call Closure defined in other script - variables

What is the correct and simplest way to access a closure defined within another script in Groovy. This might not be the best design, but I have a closure defined in
SomeScript.groovy
bindingC = {
...
}
def localC = {
...
}
OtherScript.groovy
SomeScript s = new SomeScript()
s.bindingC(...);
s.localC(...);
Note: SomeScript.groovy is program logic and OtherScript.groovy is unit testing logic. They are both in the same package and I'm able to access methods in SomeScript already.

There are two ways (i'm aware) you can use to achieve what you want; you can either instantiate the SomeScript and run its contents or you can evaluate SomeScript using groovy shell. The script needs to be executed so the variable will be created in the binding:
SomeScript.groovy:
bindingC = {
110.0
}
OtherScript.groovy solution 1:
s = new GroovyShell().evaluate new File("SomeScript.groovy")
assert s.bindingC() == 110.0
OtherScript.groovy solution 2:
s2 = new SomeScript() // SomeScript is also an instance of groovy.lang.Script
s2.run()
assert s2.bindingC() == 110.0

Related

What is the analogue of Mockito.verifyZeroInteractions(obj) in the Mockk library?

I want to switch to Mockk, but i cant find analogue of this method in Mockk
It doesn't work
verify (exactly = 0) { obj }
The way you are trying it, is missing the method or variable
verify (exactly = 0) { obj.something }
Using the exactly zero approach would require
confirmVerified(obj)
To be sure nothing else was called.
The exact equivalent would be:
verify { obj wasNot Called }

Can you verify a property setter using mockk?

We had a few tests in Java and Mockito, which we are progressively converting into Kotlin and Mockk. There's a problem, though. This simple line:
verify(mockedInteractor).setIndex(1);
When we move it to mockk, we get this:
verify { mockedInteractor.index = 1 }
This of course passes the tests, as it's not actually checking that index was set to 1. It's simply setting the mock's variable to 1. This below has the same effect.
verify { mockedInteractor.setIndex(1) }
Is there a way to verify setters?
You could try capture:
val fooSlot = slot<String>()
val mockBar = mockk<Bar>()
every { mockBar.foo = capture(fooSlot) } answers { }
assertEquals(fooSlot.captured, "expected")
Yes you can:
verify { mockedInteractor setProperty "index" value 1 }
There are more examples in here https://mockk.io/#private-functions-mocking--dynamic-calls
Compact solution without hardcoded string:
verify { mockedInteractor setProperty MockedInteractor::index.name value 1 }
where MockedInteractor is mockedInteractor class
I'm wondering if this was asked about an earlier version of Mockk, afterall, it is and old question.
verify { mockedInteractor.index = 1 }
does exactly what it says - it verifies that mockedInteractor.index was set to 1.
If you don't believe me, try it. Try setting mockedInteractor.index to something other than 1 in the product code and watch this test fail.
Maybe this was a Mockk bug that has since been fixed.
You can now relax this requirement for unit functions when defining your mock.
val foo = mockk<Foo>(relaxUnitFun = true)
Enabling this setting on your mock means you will not need to use justRun or any variation of that code (as per the Mockk documentation) when verifying unit functions are invoked.

Run specific Spock Tests without setup?

In the documentation Spock mentions these function in the section 'Fixture Methods':
def setup() {} // run before every feature method
def cleanup() {} // run after every feature method
def setupSpec() {} // run before the first feature method
def cleanupSpec() {} // run after the last feature method
I am using the setup function to initialize new objects for all tests. However some tests are supposed to test what happens when there are no other objects yet.
Because of the setup these tests fail now.
Is there any way to suspend the setup for certain functions? An annotation perhaps?
Or do I have to create a separate "setup" function and call them in each test I do. The majority of tests uses it!
You can always override value inside your test method only for that specific method. Take a look at following example:
import spock.lang.Shared
import spock.lang.Specification
class SpockDemoSpec extends Specification {
String a
String b
#Shared
String c
def setup() {
println "This method is executed before each specification"
a = "A value"
b = "B value"
}
def setupSpec() {
println "This method is executed only one time before all other specifications"
c = "C value"
}
def "A empty"() {
setup:
a = ""
when:
def result = doSomething(a)
then:
result == ""
}
def "A"() {
when:
def result = doSomething(a)
then:
result == "A VALUE"
}
def "A NullPointerException"() {
setup:
a = null
when:
def result = doSomething(a)
then:
thrown NullPointerException
}
def "C"() {
when:
def result = doSomething(c)
then:
result == 'C VALUE'
}
private String doSomething(String str) {
return str.toUpperCase()
}
}
In this example a and b are set up before each test and c is set up only once before any specification is executed (that's why it requires #Shared annotation to keep it's value between executions).
When we run this test we will see following output in the console:
This method is executed only one time before all other specifications
This method is executed before each specification
This method is executed before each specification
This method is executed before each specification
This method is executed before each specification
The general rule of thumb is that you shouldn't change c value after it is set up in setupSpec method - mostly because you don't know if which order tests are going to be executed (in case you need to guarantee the order you can annotate your class with #Stepwise annotation - Spock will run all cases in order they are defined in this case). In case of a and b you can override then at the single method level - they will get reinitialized before another test case is executed. Hope it helps.

jasmine testing on external library

I am attempting to do some basic testing using jasmine. I use an external library & what I intend to do is spy/mock the method calls on the library object (d3) and make sure appropriate methods are called on d3.
var d3Spy = jasmine.createSpyObj('d3', ['select']);
spyOn(window, 'd3').andReturn(d3Spy);
expect(d3Spy.select).toHaveBeenCalled();
When 'select' is being called on the object, I get this error.
TypeError: Object function () {
spyObj.wasCalled = true;
spyObj.callCount++;
var args = jasmine.util.argsToArray(arguments);
spyObj.mostRecentCall.object = this;
spyObj.mostRecentCall.args = args;
spyObj.argsForCall.push(args);
spyObj.calls.push({object: this, args: args});
return spyObj.plan.apply(this, arguments);
} has no method 'select'
What am I doing wrong?
The failure in your code is the following
spyOn(window, 'd3').andReturn(d3Spy);
This line wil return the spy only when you call d3(). So it replace the d3 object with a function that when its called returns the {select: jasmine.createSpy()}. But using d3 you will never call d3() cause select is a static member of d3
So the solution is just to spy on `d3.select'
spyOn(d3, 'select')
Btw. the problem with libs like D3 that use heavy chaining is, that its hard to mock. So the select spy in your example has to return the an object which fits the d3 Selections object and so on. So sometimes it would be easier to not mock out everything.

Grails 1.3.6 - Object fields seem to lose their value

I am a newbie to Grails and using an ancient version of Grails (1.3.6/8). I have an object with some variables that aren't holding on to the stuff I assign them.
class NiftyController {
try
{
SomeGrid someGrid = new SomeGrid()
def selectedDate = params.specifiedDate
...
someGrid.selectedDate = selectedDate
someGrid.longDate = Calendar.getInstance().getTimeInMillis()
println someGrid.selectedDate // prints, say, 08/06/2012
println someGrid.longDate // prints, say, 1302558890256
....
doSomeWork(someGrid)
}
def doSomeWork = { SomeGrid someGrid ->
println someGrid.selectedDate // prints '' (empty)
println someGrid.longDate // prints 8 - the number for the current month.
}
}
I am totally scratching my head - I work with Java and this type of loss of assigned variable data is new and makes no sense to me at all. Can anyone figure out what is going on here? I would guess it is some kind of visibility problem unique to Grails, but I can't nail it.
Any help is greatly appreciated!
If doSomeWork doesn't itself need to be a controller action, I would make it a normal method instead of a closure:
private doSomeWork(SomeGrid someGrid) {
//...
}
With it as a closure, Grails may be treating the SomeGrid parameter as a command object and trying to data-bind it directly from the params.