Closed PavelKa closed 3 years ago
Hi,
You should not mock the class under testing and var1 is that. Rather mock the external function calls in callMocked().Hi, You schould not mock the class under test.
You should not mock the class under testing and var1 is that. Rather mock the external function calls in callMocked().
Hi, the example is very simplified. I need to create a test for legacy implementation where many global methods in one file (var1) exist. These global methods call each other so it would be very useful to mock also methods in the tested class (var1) and have the possibility to test that mocked method was called with expected parameters values in the same way as getPipelineMock does. As a workaround, I rewrite the static method in the test method and add a test to this mock, although getPipelineMock would be more straightforward.
//vars/var1.groovy
def callMocked(){
toMock("XXX")
}
def toMock( x ) {
"not mocked"
}
Mocking method in the same class:
xVar1.metaClass.static.toMock << { x->
assert "XXX" == x
"mocked2"
}
That's a tough situation.
You say "legacy" - does this mean you are unable to make changes to the source code of the project that contains var1
? That would be the most-correct, best, and easiest place to write tests for the functionality in var1
. It will be much harder (especially if the methods call each other) to test var1
from outside that project.
Arguably, that's not a problem that unit-test frameworks are even charged with solving.
You need a Spock Spy to be able to stub/mock individual methods on a real object, to enable testing of a single method (that calls other methods on the same object) in isolation.
However, to load the "random" groovy Script into something that can call Jenkins pipeline steps, you need loadPipelineScriptForTest
which ... creates its own special implementation (that is not a spy) to enable the above.
In your case, the metaClass
method you have found is the best way to unit-test individual methods on a class outside your project, where those methods call each other. (You're essentially manually spying on the PipelineVariableImpersonator
object that jenkins-spock
creates to represent var1.groovy
).
The problem isn't fundamentally a problem for jenkins-spock
, but for the unit-testing framework (vanilla spock
) in general.
Desired Behavior
If multiple methods are defined in vars. e.g. :
then it would be useful to have the possibility to easy mock methods in the tested script.. following test will fail because var1.toMock is not mocked :
Mocking of methods in scripts that are not tested/ loaded using loadPipelineScriptForTest works as expected and can be mocked using getPipelineMock e.g.:
Benefits