Groovy mocking with and without closure: behaviour seems odd
I have two classes that I'm testing.
They both have two functions (outer and inner).
I want to see what parameters have been passed to inner.
So, I mock inner using MockFor (mock.demand.inner) with another Closure.
The first class returns a Closure which will call inner. Then the Closure is executed by the test. It works, the original inner is not called.
The second class executes inner directly. It fails, the original inner is called.
I've tried to mock it by overriding it (Can Groovy dynamically add or override a method on a POJO?) and the original inner is still called.
The thing is, I must call inner from within outer with the second class. I cannot delay it or delegate it.
So, I'm wondering what is going on there? How can I make it work?
Here is the code, stripped down, from 1500+ lines, to 66 lines, isolating and highlighting the actual behaviour.
To know if inner is not correctly mocked, it throws an exception. This will be thrown only if it's not mocked.
package org.aroundmedia.tools
import groovy.mock.interceptor.MockFor
import org.junit.Test
import sun.reflect.generics.reflectiveObjects.NotImplementedException
class ClassWithClosure {
def outer() {
return { this.inner('foo') }
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ClassWithoutClosure {
def outer() {
this.inner('foo')
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ParameterizedTestsForPostAlways extends GroovyTestCase {
@Test
void testWithClosure() {
def mock = new MockFor(ClassWithClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithClosure()
def closure = instance.outer()
closure()
}
assert res == ["foo"]
}
@Test
void testWithoutClosure() {
def mock = new MockFor(ClassWithoutClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithoutClosure()
instance.outer()
}
assert res == ["foo"]
}
@Test
void testOverrideWithoutClosure() {
ClassWithoutClosure inst = new ClassWithoutClosure()
def res =
inst.metaClass.inner = {a -> res.add(a)}
inst.outer()
assert res == ['foo']
}
}
unit-testing groovy
add a comment |
I have two classes that I'm testing.
They both have two functions (outer and inner).
I want to see what parameters have been passed to inner.
So, I mock inner using MockFor (mock.demand.inner) with another Closure.
The first class returns a Closure which will call inner. Then the Closure is executed by the test. It works, the original inner is not called.
The second class executes inner directly. It fails, the original inner is called.
I've tried to mock it by overriding it (Can Groovy dynamically add or override a method on a POJO?) and the original inner is still called.
The thing is, I must call inner from within outer with the second class. I cannot delay it or delegate it.
So, I'm wondering what is going on there? How can I make it work?
Here is the code, stripped down, from 1500+ lines, to 66 lines, isolating and highlighting the actual behaviour.
To know if inner is not correctly mocked, it throws an exception. This will be thrown only if it's not mocked.
package org.aroundmedia.tools
import groovy.mock.interceptor.MockFor
import org.junit.Test
import sun.reflect.generics.reflectiveObjects.NotImplementedException
class ClassWithClosure {
def outer() {
return { this.inner('foo') }
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ClassWithoutClosure {
def outer() {
this.inner('foo')
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ParameterizedTestsForPostAlways extends GroovyTestCase {
@Test
void testWithClosure() {
def mock = new MockFor(ClassWithClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithClosure()
def closure = instance.outer()
closure()
}
assert res == ["foo"]
}
@Test
void testWithoutClosure() {
def mock = new MockFor(ClassWithoutClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithoutClosure()
instance.outer()
}
assert res == ["foo"]
}
@Test
void testOverrideWithoutClosure() {
ClassWithoutClosure inst = new ClassWithoutClosure()
def res =
inst.metaClass.inner = {a -> res.add(a)}
inst.outer()
assert res == ['foo']
}
}
unit-testing groovy
add a comment |
I have two classes that I'm testing.
They both have two functions (outer and inner).
I want to see what parameters have been passed to inner.
So, I mock inner using MockFor (mock.demand.inner) with another Closure.
The first class returns a Closure which will call inner. Then the Closure is executed by the test. It works, the original inner is not called.
The second class executes inner directly. It fails, the original inner is called.
I've tried to mock it by overriding it (Can Groovy dynamically add or override a method on a POJO?) and the original inner is still called.
The thing is, I must call inner from within outer with the second class. I cannot delay it or delegate it.
So, I'm wondering what is going on there? How can I make it work?
Here is the code, stripped down, from 1500+ lines, to 66 lines, isolating and highlighting the actual behaviour.
To know if inner is not correctly mocked, it throws an exception. This will be thrown only if it's not mocked.
package org.aroundmedia.tools
import groovy.mock.interceptor.MockFor
import org.junit.Test
import sun.reflect.generics.reflectiveObjects.NotImplementedException
class ClassWithClosure {
def outer() {
return { this.inner('foo') }
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ClassWithoutClosure {
def outer() {
this.inner('foo')
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ParameterizedTestsForPostAlways extends GroovyTestCase {
@Test
void testWithClosure() {
def mock = new MockFor(ClassWithClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithClosure()
def closure = instance.outer()
closure()
}
assert res == ["foo"]
}
@Test
void testWithoutClosure() {
def mock = new MockFor(ClassWithoutClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithoutClosure()
instance.outer()
}
assert res == ["foo"]
}
@Test
void testOverrideWithoutClosure() {
ClassWithoutClosure inst = new ClassWithoutClosure()
def res =
inst.metaClass.inner = {a -> res.add(a)}
inst.outer()
assert res == ['foo']
}
}
unit-testing groovy
I have two classes that I'm testing.
They both have two functions (outer and inner).
I want to see what parameters have been passed to inner.
So, I mock inner using MockFor (mock.demand.inner) with another Closure.
The first class returns a Closure which will call inner. Then the Closure is executed by the test. It works, the original inner is not called.
The second class executes inner directly. It fails, the original inner is called.
I've tried to mock it by overriding it (Can Groovy dynamically add or override a method on a POJO?) and the original inner is still called.
The thing is, I must call inner from within outer with the second class. I cannot delay it or delegate it.
So, I'm wondering what is going on there? How can I make it work?
Here is the code, stripped down, from 1500+ lines, to 66 lines, isolating and highlighting the actual behaviour.
To know if inner is not correctly mocked, it throws an exception. This will be thrown only if it's not mocked.
package org.aroundmedia.tools
import groovy.mock.interceptor.MockFor
import org.junit.Test
import sun.reflect.generics.reflectiveObjects.NotImplementedException
class ClassWithClosure {
def outer() {
return { this.inner('foo') }
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ClassWithoutClosure {
def outer() {
this.inner('foo')
}
private def inner(arg) {
throw new NotImplementedException()
}
}
class ParameterizedTestsForPostAlways extends GroovyTestCase {
@Test
void testWithClosure() {
def mock = new MockFor(ClassWithClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithClosure()
def closure = instance.outer()
closure()
}
assert res == ["foo"]
}
@Test
void testWithoutClosure() {
def mock = new MockFor(ClassWithoutClosure)
mock.ignore('outer')
def res =
mock.demand.inner {a -> res.add(a)}
mock.use {
def instance = new ClassWithoutClosure()
instance.outer()
}
assert res == ["foo"]
}
@Test
void testOverrideWithoutClosure() {
ClassWithoutClosure inst = new ClassWithoutClosure()
def res =
inst.metaClass.inner = {a -> res.add(a)}
inst.outer()
assert res == ['foo']
}
}
unit-testing groovy
unit-testing groovy
asked Nov 22 at 16:31
Samuel GIFFARD
383112
383112
add a comment |
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435059%2fgroovy-mocking-with-and-without-closure-behaviour-seems-odd%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435059%2fgroovy-mocking-with-and-without-closure-behaviour-seems-odd%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown