Groovy mocking with and without closure: behaviour seems odd












0














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']
}
}









share|improve this question



























    0














    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']
    }
    }









    share|improve this question

























      0












      0








      0







      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']
      }
      }









      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 at 16:31









      Samuel GIFFARD

      383112




      383112





























          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
          });


          }
          });














          draft saved

          draft discarded


















          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
















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Berounka

          Sphinx de Gizeh

          Different font size/position of beamer's navigation symbols template's content depending on regular/plain...