Matching JdbcTemplate update method with Mockito












1















I am trying to match this method which I have used in my Dao class. But I always get the following exception indicating that the call was not made on the method.



It's either the method is not matched, or I am doing something wrong.



String pSql = "SELECT * FROM employee";
Object pArgs = new Object {""};
int pArgTypes = new int {};

/* Return 1 when the call to update() is made indicating a successful database update */
when(mJdbcTemplate.update(anyString(), aryEq(pArgs), aryEq(pArgTypes))).thenReturn(1);


Here is the stack trace of the exception:



Wanted but not invoked:
jdbcTemplate.update(<any>, <any>, <any>);
-> at com.test.GenericDaoJdbcImplTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)

However, there were other interactions with this mock:
-> at com.test.GenericDaoJdbcImplTest.insertUpdateDelete(GenericDaoJdbcImpl.java:121)

at org.mockito.exceptions.Reporter.wantedButNotInvoked(Reporter.java:269)
at org.mockito.internal.verification.checkers.MissingInvocationChecker.check(MissingInvocationChecker.java:42)
at org.mockito.internal.verification.Times.verify(Times.java:36)
at org.mockito.internal.verification.MockAwareVerificationMode.verify(MockAwareVerificationMode.java:21)
at org.mockito.internal.MockHandler.handle(MockHandler.java:80)
at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByMockitoWithCGLIB$$92326890.update(<generated>)
at com.test.GenericDaoJdbcImplTestTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


My GenericDaoJdbcImplTest is an abstract class. Here is the class which I am testing.



public abstract class GenericDaoJdbcImpl<MODEL, PRIMARYKEY extends Serializable>
implements GenericJdbcDao<MODEL, PRIMARYKEY> {

@Autowired
@Qualifier(value = "jdbcTemplate")
private JdbcTemplate mJdbcTemplate;

private Class<MODEL> mType;

public JdbcTemplate getJdbcTemplate() {
return mJdbcTemplate;
}

public void setJdbcTemplate(final JdbcTemplate pJdbcTemplate) {
this.mJdbcTemplate = pJdbcTemplate;
}

public GenericDaoJdbcImpl(final Class<MODEL> pType) {
this.mType = pType;
}

public abstract MODEL add(final MODEL mModel);

public abstract MODEL modify(final MODEL mModel);

public abstract MODEL read(PRIMARYKEY pId);

public abstract List<MODEL> list();

public abstract void delete(PRIMARYKEY pId);

@Override
public boolean insertUpdateDelete(final String pSql, final Object pArgs,
final int pArgTypes) {

Assert.hasLength(pSql, "No SQL provided to execute");
Assert.notNull(pArgs, "No data provided to insert/update/delete");
Assert.notNull(pArgTypes, "No data types provided for");
Assert.isTrue(pArgs.length == pArgTypes.length, "Mis-match in data and data type count");

return (mJdbcTemplate.update(pSql, pArgs, pArgTypes) > 0);
}
}









share|improve this question



























    1















    I am trying to match this method which I have used in my Dao class. But I always get the following exception indicating that the call was not made on the method.



    It's either the method is not matched, or I am doing something wrong.



    String pSql = "SELECT * FROM employee";
    Object pArgs = new Object {""};
    int pArgTypes = new int {};

    /* Return 1 when the call to update() is made indicating a successful database update */
    when(mJdbcTemplate.update(anyString(), aryEq(pArgs), aryEq(pArgTypes))).thenReturn(1);


    Here is the stack trace of the exception:



    Wanted but not invoked:
    jdbcTemplate.update(<any>, <any>, <any>);
    -> at com.test.GenericDaoJdbcImplTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)

    However, there were other interactions with this mock:
    -> at com.test.GenericDaoJdbcImplTest.insertUpdateDelete(GenericDaoJdbcImpl.java:121)

    at org.mockito.exceptions.Reporter.wantedButNotInvoked(Reporter.java:269)
    at org.mockito.internal.verification.checkers.MissingInvocationChecker.check(MissingInvocationChecker.java:42)
    at org.mockito.internal.verification.Times.verify(Times.java:36)
    at org.mockito.internal.verification.MockAwareVerificationMode.verify(MockAwareVerificationMode.java:21)
    at org.mockito.internal.MockHandler.handle(MockHandler.java:80)
    at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
    at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
    at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByMockitoWithCGLIB$$92326890.update(<generated>)
    at com.test.GenericDaoJdbcImplTestTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


    My GenericDaoJdbcImplTest is an abstract class. Here is the class which I am testing.



    public abstract class GenericDaoJdbcImpl<MODEL, PRIMARYKEY extends Serializable>
    implements GenericJdbcDao<MODEL, PRIMARYKEY> {

    @Autowired
    @Qualifier(value = "jdbcTemplate")
    private JdbcTemplate mJdbcTemplate;

    private Class<MODEL> mType;

    public JdbcTemplate getJdbcTemplate() {
    return mJdbcTemplate;
    }

    public void setJdbcTemplate(final JdbcTemplate pJdbcTemplate) {
    this.mJdbcTemplate = pJdbcTemplate;
    }

    public GenericDaoJdbcImpl(final Class<MODEL> pType) {
    this.mType = pType;
    }

    public abstract MODEL add(final MODEL mModel);

    public abstract MODEL modify(final MODEL mModel);

    public abstract MODEL read(PRIMARYKEY pId);

    public abstract List<MODEL> list();

    public abstract void delete(PRIMARYKEY pId);

    @Override
    public boolean insertUpdateDelete(final String pSql, final Object pArgs,
    final int pArgTypes) {

    Assert.hasLength(pSql, "No SQL provided to execute");
    Assert.notNull(pArgs, "No data provided to insert/update/delete");
    Assert.notNull(pArgTypes, "No data types provided for");
    Assert.isTrue(pArgs.length == pArgTypes.length, "Mis-match in data and data type count");

    return (mJdbcTemplate.update(pSql, pArgs, pArgTypes) > 0);
    }
    }









    share|improve this question

























      1












      1








      1


      0






      I am trying to match this method which I have used in my Dao class. But I always get the following exception indicating that the call was not made on the method.



      It's either the method is not matched, or I am doing something wrong.



      String pSql = "SELECT * FROM employee";
      Object pArgs = new Object {""};
      int pArgTypes = new int {};

      /* Return 1 when the call to update() is made indicating a successful database update */
      when(mJdbcTemplate.update(anyString(), aryEq(pArgs), aryEq(pArgTypes))).thenReturn(1);


      Here is the stack trace of the exception:



      Wanted but not invoked:
      jdbcTemplate.update(<any>, <any>, <any>);
      -> at com.test.GenericDaoJdbcImplTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)

      However, there were other interactions with this mock:
      -> at com.test.GenericDaoJdbcImplTest.insertUpdateDelete(GenericDaoJdbcImpl.java:121)

      at org.mockito.exceptions.Reporter.wantedButNotInvoked(Reporter.java:269)
      at org.mockito.internal.verification.checkers.MissingInvocationChecker.check(MissingInvocationChecker.java:42)
      at org.mockito.internal.verification.Times.verify(Times.java:36)
      at org.mockito.internal.verification.MockAwareVerificationMode.verify(MockAwareVerificationMode.java:21)
      at org.mockito.internal.MockHandler.handle(MockHandler.java:80)
      at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
      at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
      at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByMockitoWithCGLIB$$92326890.update(<generated>)
      at com.test.GenericDaoJdbcImplTestTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


      My GenericDaoJdbcImplTest is an abstract class. Here is the class which I am testing.



      public abstract class GenericDaoJdbcImpl<MODEL, PRIMARYKEY extends Serializable>
      implements GenericJdbcDao<MODEL, PRIMARYKEY> {

      @Autowired
      @Qualifier(value = "jdbcTemplate")
      private JdbcTemplate mJdbcTemplate;

      private Class<MODEL> mType;

      public JdbcTemplate getJdbcTemplate() {
      return mJdbcTemplate;
      }

      public void setJdbcTemplate(final JdbcTemplate pJdbcTemplate) {
      this.mJdbcTemplate = pJdbcTemplate;
      }

      public GenericDaoJdbcImpl(final Class<MODEL> pType) {
      this.mType = pType;
      }

      public abstract MODEL add(final MODEL mModel);

      public abstract MODEL modify(final MODEL mModel);

      public abstract MODEL read(PRIMARYKEY pId);

      public abstract List<MODEL> list();

      public abstract void delete(PRIMARYKEY pId);

      @Override
      public boolean insertUpdateDelete(final String pSql, final Object pArgs,
      final int pArgTypes) {

      Assert.hasLength(pSql, "No SQL provided to execute");
      Assert.notNull(pArgs, "No data provided to insert/update/delete");
      Assert.notNull(pArgTypes, "No data types provided for");
      Assert.isTrue(pArgs.length == pArgTypes.length, "Mis-match in data and data type count");

      return (mJdbcTemplate.update(pSql, pArgs, pArgTypes) > 0);
      }
      }









      share|improve this question














      I am trying to match this method which I have used in my Dao class. But I always get the following exception indicating that the call was not made on the method.



      It's either the method is not matched, or I am doing something wrong.



      String pSql = "SELECT * FROM employee";
      Object pArgs = new Object {""};
      int pArgTypes = new int {};

      /* Return 1 when the call to update() is made indicating a successful database update */
      when(mJdbcTemplate.update(anyString(), aryEq(pArgs), aryEq(pArgTypes))).thenReturn(1);


      Here is the stack trace of the exception:



      Wanted but not invoked:
      jdbcTemplate.update(<any>, <any>, <any>);
      -> at com.test.GenericDaoJdbcImplTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)

      However, there were other interactions with this mock:
      -> at com.test.GenericDaoJdbcImplTest.insertUpdateDelete(GenericDaoJdbcImpl.java:121)

      at org.mockito.exceptions.Reporter.wantedButNotInvoked(Reporter.java:269)
      at org.mockito.internal.verification.checkers.MissingInvocationChecker.check(MissingInvocationChecker.java:42)
      at org.mockito.internal.verification.Times.verify(Times.java:36)
      at org.mockito.internal.verification.MockAwareVerificationMode.verify(MockAwareVerificationMode.java:21)
      at org.mockito.internal.MockHandler.handle(MockHandler.java:80)
      at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
      at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48)
      at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByMockitoWithCGLIB$$92326890.update(<generated>)
      at com.test.GenericDaoJdbcImplTestTest$WhenInsertUpdateDeleteIsCalledWith.successfulUpdateShouldReturnTrue(GenericDaoJdbcImplTest.java:197)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


      My GenericDaoJdbcImplTest is an abstract class. Here is the class which I am testing.



      public abstract class GenericDaoJdbcImpl<MODEL, PRIMARYKEY extends Serializable>
      implements GenericJdbcDao<MODEL, PRIMARYKEY> {

      @Autowired
      @Qualifier(value = "jdbcTemplate")
      private JdbcTemplate mJdbcTemplate;

      private Class<MODEL> mType;

      public JdbcTemplate getJdbcTemplate() {
      return mJdbcTemplate;
      }

      public void setJdbcTemplate(final JdbcTemplate pJdbcTemplate) {
      this.mJdbcTemplate = pJdbcTemplate;
      }

      public GenericDaoJdbcImpl(final Class<MODEL> pType) {
      this.mType = pType;
      }

      public abstract MODEL add(final MODEL mModel);

      public abstract MODEL modify(final MODEL mModel);

      public abstract MODEL read(PRIMARYKEY pId);

      public abstract List<MODEL> list();

      public abstract void delete(PRIMARYKEY pId);

      @Override
      public boolean insertUpdateDelete(final String pSql, final Object pArgs,
      final int pArgTypes) {

      Assert.hasLength(pSql, "No SQL provided to execute");
      Assert.notNull(pArgs, "No data provided to insert/update/delete");
      Assert.notNull(pArgTypes, "No data types provided for");
      Assert.isTrue(pArgs.length == pArgTypes.length, "Mis-match in data and data type count");

      return (mJdbcTemplate.update(pSql, pArgs, pArgTypes) > 0);
      }
      }






      java junit junit4 mockito






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jul 17 '13 at 8:40









      divinedragondivinedragon

      1,77093260




      1,77093260
























          3 Answers
          3






          active

          oldest

          votes


















          2














          Try using an ArgumentCaptor, these conditions tend to be less restrictive and allow for validating complex arguments after the call.



          @Captor
          ArgumentCaptor<Object> objCap;
          @Captor
          ArgumentCaptor<int> intCap;

          when(mJdbcTemplate.update(anyString(), objCap.capture(), intCap.capture())).thenReturn(1);





          share|improve this answer
























          • Aah. Why didn't I think of those. Let me try those. Thanks.

            – divinedragon
            Jul 17 '13 at 12:47











          • If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

            – Dawood ibn Kareem
            Jul 17 '13 at 21:43



















          2














          You have to cast the arguments in your when call. Otherwise the arguments will be ambiguous and the compiler is unable to resolve it to a specific update method.



          So:



          Mockito.when(jdbcTemplate.update((String)Mockito.anyString(), (Object)Mockito.anyVararg())).thenReturn(var);


          should resolve your issue. At least it did for me.






          share|improve this answer































            0














            Don't mock type you don't own! That's one of the big principle. Mocking these types have a a negative impact the the tests in more than just one way :




            1. It complexify your test, potentially making it difficult to craft, read, understand or refactor

            2. You have to understand how is used this type.

            3. It augments the coupling of the test with this implementation, version, etc

            4. It gives you a false sense of security, because you have mokced the behavior so the test is passing, but the real code might have changed the behavior or see new behavior for a new version, and then you'll see a boom on the server!


            In your case you are testing something at the boundary of your system, so the thumb rule would be to write integration test when dealing with databases, etc. and write unit test for your business code.



            I heavily recommend the Growing Object Oriented Software - Guided by tests book. I think it's probably one of the most useful book to help write good software using TDD. Plus it has been written by the authors of the first mock framework, Steve Freeman and Nat Pryce.






            share|improve this answer
























            • Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

              – divinedragon
              Jul 17 '13 at 9:48











            • One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

              – John B
              Jul 17 '13 at 12:16











            • I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

              – divinedragon
              Jul 17 '13 at 12:46











            • @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

              – Brice
              Jul 17 '13 at 15:01











            • @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

              – Brice
              Jul 17 '13 at 15:14











            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%2f17695056%2fmatching-jdbctemplate-update-method-with-mockito%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Try using an ArgumentCaptor, these conditions tend to be less restrictive and allow for validating complex arguments after the call.



            @Captor
            ArgumentCaptor<Object> objCap;
            @Captor
            ArgumentCaptor<int> intCap;

            when(mJdbcTemplate.update(anyString(), objCap.capture(), intCap.capture())).thenReturn(1);





            share|improve this answer
























            • Aah. Why didn't I think of those. Let me try those. Thanks.

              – divinedragon
              Jul 17 '13 at 12:47











            • If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

              – Dawood ibn Kareem
              Jul 17 '13 at 21:43
















            2














            Try using an ArgumentCaptor, these conditions tend to be less restrictive and allow for validating complex arguments after the call.



            @Captor
            ArgumentCaptor<Object> objCap;
            @Captor
            ArgumentCaptor<int> intCap;

            when(mJdbcTemplate.update(anyString(), objCap.capture(), intCap.capture())).thenReturn(1);





            share|improve this answer
























            • Aah. Why didn't I think of those. Let me try those. Thanks.

              – divinedragon
              Jul 17 '13 at 12:47











            • If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

              – Dawood ibn Kareem
              Jul 17 '13 at 21:43














            2












            2








            2







            Try using an ArgumentCaptor, these conditions tend to be less restrictive and allow for validating complex arguments after the call.



            @Captor
            ArgumentCaptor<Object> objCap;
            @Captor
            ArgumentCaptor<int> intCap;

            when(mJdbcTemplate.update(anyString(), objCap.capture(), intCap.capture())).thenReturn(1);





            share|improve this answer













            Try using an ArgumentCaptor, these conditions tend to be less restrictive and allow for validating complex arguments after the call.



            @Captor
            ArgumentCaptor<Object> objCap;
            @Captor
            ArgumentCaptor<int> intCap;

            when(mJdbcTemplate.update(anyString(), objCap.capture(), intCap.capture())).thenReturn(1);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 17 '13 at 12:19









            John BJohn B

            26.5k55483




            26.5k55483













            • Aah. Why didn't I think of those. Let me try those. Thanks.

              – divinedragon
              Jul 17 '13 at 12:47











            • If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

              – Dawood ibn Kareem
              Jul 17 '13 at 21:43



















            • Aah. Why didn't I think of those. Let me try those. Thanks.

              – divinedragon
              Jul 17 '13 at 12:47











            • If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

              – Dawood ibn Kareem
              Jul 17 '13 at 21:43

















            Aah. Why didn't I think of those. Let me try those. Thanks.

            – divinedragon
            Jul 17 '13 at 12:47





            Aah. Why didn't I think of those. Let me try those. Thanks.

            – divinedragon
            Jul 17 '13 at 12:47













            If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

            – Dawood ibn Kareem
            Jul 17 '13 at 21:43





            If jdbcTemplate.update(<any>, <any>, <any>) is not being invoked, as the stack trace suggests, then using an ArgumentCaptor isn't going to help in any way.

            – Dawood ibn Kareem
            Jul 17 '13 at 21:43













            2














            You have to cast the arguments in your when call. Otherwise the arguments will be ambiguous and the compiler is unable to resolve it to a specific update method.



            So:



            Mockito.when(jdbcTemplate.update((String)Mockito.anyString(), (Object)Mockito.anyVararg())).thenReturn(var);


            should resolve your issue. At least it did for me.






            share|improve this answer




























              2














              You have to cast the arguments in your when call. Otherwise the arguments will be ambiguous and the compiler is unable to resolve it to a specific update method.



              So:



              Mockito.when(jdbcTemplate.update((String)Mockito.anyString(), (Object)Mockito.anyVararg())).thenReturn(var);


              should resolve your issue. At least it did for me.






              share|improve this answer


























                2












                2








                2







                You have to cast the arguments in your when call. Otherwise the arguments will be ambiguous and the compiler is unable to resolve it to a specific update method.



                So:



                Mockito.when(jdbcTemplate.update((String)Mockito.anyString(), (Object)Mockito.anyVararg())).thenReturn(var);


                should resolve your issue. At least it did for me.






                share|improve this answer













                You have to cast the arguments in your when call. Otherwise the arguments will be ambiguous and the compiler is unable to resolve it to a specific update method.



                So:



                Mockito.when(jdbcTemplate.update((String)Mockito.anyString(), (Object)Mockito.anyVararg())).thenReturn(var);


                should resolve your issue. At least it did for me.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 13 '18 at 4:11









                Paul WarrenPaul Warren

                1,1431817




                1,1431817























                    0














                    Don't mock type you don't own! That's one of the big principle. Mocking these types have a a negative impact the the tests in more than just one way :




                    1. It complexify your test, potentially making it difficult to craft, read, understand or refactor

                    2. You have to understand how is used this type.

                    3. It augments the coupling of the test with this implementation, version, etc

                    4. It gives you a false sense of security, because you have mokced the behavior so the test is passing, but the real code might have changed the behavior or see new behavior for a new version, and then you'll see a boom on the server!


                    In your case you are testing something at the boundary of your system, so the thumb rule would be to write integration test when dealing with databases, etc. and write unit test for your business code.



                    I heavily recommend the Growing Object Oriented Software - Guided by tests book. I think it's probably one of the most useful book to help write good software using TDD. Plus it has been written by the authors of the first mock framework, Steve Freeman and Nat Pryce.






                    share|improve this answer
























                    • Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                      – divinedragon
                      Jul 17 '13 at 9:48











                    • One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                      – John B
                      Jul 17 '13 at 12:16











                    • I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                      – divinedragon
                      Jul 17 '13 at 12:46











                    • @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                      – Brice
                      Jul 17 '13 at 15:01











                    • @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                      – Brice
                      Jul 17 '13 at 15:14
















                    0














                    Don't mock type you don't own! That's one of the big principle. Mocking these types have a a negative impact the the tests in more than just one way :




                    1. It complexify your test, potentially making it difficult to craft, read, understand or refactor

                    2. You have to understand how is used this type.

                    3. It augments the coupling of the test with this implementation, version, etc

                    4. It gives you a false sense of security, because you have mokced the behavior so the test is passing, but the real code might have changed the behavior or see new behavior for a new version, and then you'll see a boom on the server!


                    In your case you are testing something at the boundary of your system, so the thumb rule would be to write integration test when dealing with databases, etc. and write unit test for your business code.



                    I heavily recommend the Growing Object Oriented Software - Guided by tests book. I think it's probably one of the most useful book to help write good software using TDD. Plus it has been written by the authors of the first mock framework, Steve Freeman and Nat Pryce.






                    share|improve this answer
























                    • Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                      – divinedragon
                      Jul 17 '13 at 9:48











                    • One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                      – John B
                      Jul 17 '13 at 12:16











                    • I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                      – divinedragon
                      Jul 17 '13 at 12:46











                    • @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                      – Brice
                      Jul 17 '13 at 15:01











                    • @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                      – Brice
                      Jul 17 '13 at 15:14














                    0












                    0








                    0







                    Don't mock type you don't own! That's one of the big principle. Mocking these types have a a negative impact the the tests in more than just one way :




                    1. It complexify your test, potentially making it difficult to craft, read, understand or refactor

                    2. You have to understand how is used this type.

                    3. It augments the coupling of the test with this implementation, version, etc

                    4. It gives you a false sense of security, because you have mokced the behavior so the test is passing, but the real code might have changed the behavior or see new behavior for a new version, and then you'll see a boom on the server!


                    In your case you are testing something at the boundary of your system, so the thumb rule would be to write integration test when dealing with databases, etc. and write unit test for your business code.



                    I heavily recommend the Growing Object Oriented Software - Guided by tests book. I think it's probably one of the most useful book to help write good software using TDD. Plus it has been written by the authors of the first mock framework, Steve Freeman and Nat Pryce.






                    share|improve this answer













                    Don't mock type you don't own! That's one of the big principle. Mocking these types have a a negative impact the the tests in more than just one way :




                    1. It complexify your test, potentially making it difficult to craft, read, understand or refactor

                    2. You have to understand how is used this type.

                    3. It augments the coupling of the test with this implementation, version, etc

                    4. It gives you a false sense of security, because you have mokced the behavior so the test is passing, but the real code might have changed the behavior or see new behavior for a new version, and then you'll see a boom on the server!


                    In your case you are testing something at the boundary of your system, so the thumb rule would be to write integration test when dealing with databases, etc. and write unit test for your business code.



                    I heavily recommend the Growing Object Oriented Software - Guided by tests book. I think it's probably one of the most useful book to help write good software using TDD. Plus it has been written by the authors of the first mock framework, Steve Freeman and Nat Pryce.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jul 17 '13 at 9:24









                    BriceBrice

                    23.6k36781




                    23.6k36781













                    • Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                      – divinedragon
                      Jul 17 '13 at 9:48











                    • One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                      – John B
                      Jul 17 '13 at 12:16











                    • I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                      – divinedragon
                      Jul 17 '13 at 12:46











                    • @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                      – Brice
                      Jul 17 '13 at 15:01











                    • @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                      – Brice
                      Jul 17 '13 at 15:14



















                    • Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                      – divinedragon
                      Jul 17 '13 at 9:48











                    • One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                      – John B
                      Jul 17 '13 at 12:16











                    • I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                      – divinedragon
                      Jul 17 '13 at 12:46











                    • @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                      – Brice
                      Jul 17 '13 at 15:01











                    • @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                      – Brice
                      Jul 17 '13 at 15:14

















                    Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                    – divinedragon
                    Jul 17 '13 at 9:48





                    Ok. But what if the JdbcTemplate is replaced with a separate business class. I mean I want to why the matching is not happening? The code detects that the separate method call was made on a similar method, but it doesn't match that. Why so?

                    – divinedragon
                    Jul 17 '13 at 9:48













                    One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                    – John B
                    Jul 17 '13 at 12:16





                    One of the main reasons to use mocks is to mock classes you don't own that might have complex code that is difficult to exercise every path. This allows you to exercise all options specified by the API. The point of a Unit test is that you test the component in isolation. This doesn't mean in isolation of everything but what you own. Also, I disagree with your statement that this makes tests more difficult, I find it much easier to understand setting a mock to do X than setting up all 15 conditions that drive the class to do X.

                    – John B
                    Jul 17 '13 at 12:16













                    I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                    – divinedragon
                    Jul 17 '13 at 12:46





                    I agree with @JohnB. I don't know about the principles; well not all. But the whole purpose of Unit testing is testing the class in isolation. And if I don't mock out the JdbcTemplate, then I have to setup a dummy database or use hsqldb to run my unit testing, which essentially violates the basic principle of "Unit" testing.

                    – divinedragon
                    Jul 17 '13 at 12:46













                    @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                    – Brice
                    Jul 17 '13 at 15:01





                    @divinedragon Yeah precisely I recommend for these kind of test an integration test, not a unit test. I've seen more harm done to a project in the long run when trying to mock types not owned precisely for the reason I quoted. Also test isolation is not a valid argument, as isolation doesn't have to be adapted to the test being done, for unit test you'd want to isolate unwanted behavior for collaborators, for integration test you'd want to isolate unwanted behavior at higher level.

                    – Brice
                    Jul 17 '13 at 15:01













                    @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                    – Brice
                    Jul 17 '13 at 15:14





                    @JohnB That principle is not a hard line, but ignoring it often, you'll obtain poorly designed code, with tight coupling between test, business and dependency. Instead of focusing time on this I'd rather ensure the whole behavior with the external lib/system is correct than ensuring the interactions match what is written in the code. About fixture this a different topic, integration tests don't always need that 15 conditions. If you search google about don't mock type you don't own you'll find a few stories about guys that tried and failed, and on the mockito mailinglist just as much.

                    – Brice
                    Jul 17 '13 at 15:14


















                    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.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17695056%2fmatching-jdbctemplate-update-method-with-mockito%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