Matching JdbcTemplate update method with Mockito
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
add a comment |
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
add a comment |
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
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
java junit junit4 mockito
asked Jul 17 '13 at 8:40
divinedragondivinedragon
1,77093260
1,77093260
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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);
Aah. Why didn't I think of those. Let me try those. Thanks.
– divinedragon
Jul 17 '13 at 12:47
IfjdbcTemplate.update(<any>, <any>, <any>)is not being invoked, as the stack trace suggests, then using anArgumentCaptorisn't going to help in any way.
– Dawood ibn Kareem
Jul 17 '13 at 21:43
add a comment |
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.
add a comment |
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 :
- It complexify your test, potentially making it difficult to craft, read, understand or refactor
- You have to understand how is used this type.
- It augments the coupling of the test with this implementation, version, etc
- 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.
Ok. But what if theJdbcTemplateis 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
add a comment |
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%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
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);
Aah. Why didn't I think of those. Let me try those. Thanks.
– divinedragon
Jul 17 '13 at 12:47
IfjdbcTemplate.update(<any>, <any>, <any>)is not being invoked, as the stack trace suggests, then using anArgumentCaptorisn't going to help in any way.
– Dawood ibn Kareem
Jul 17 '13 at 21:43
add a comment |
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);
Aah. Why didn't I think of those. Let me try those. Thanks.
– divinedragon
Jul 17 '13 at 12:47
IfjdbcTemplate.update(<any>, <any>, <any>)is not being invoked, as the stack trace suggests, then using anArgumentCaptorisn't going to help in any way.
– Dawood ibn Kareem
Jul 17 '13 at 21:43
add a comment |
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);
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);
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
IfjdbcTemplate.update(<any>, <any>, <any>)is not being invoked, as the stack trace suggests, then using anArgumentCaptorisn't going to help in any way.
– Dawood ibn Kareem
Jul 17 '13 at 21:43
add a comment |
Aah. Why didn't I think of those. Let me try those. Thanks.
– divinedragon
Jul 17 '13 at 12:47
IfjdbcTemplate.update(<any>, <any>, <any>)is not being invoked, as the stack trace suggests, then using anArgumentCaptorisn'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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 13 '18 at 4:11
Paul WarrenPaul Warren
1,1431817
1,1431817
add a comment |
add a comment |
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 :
- It complexify your test, potentially making it difficult to craft, read, understand or refactor
- You have to understand how is used this type.
- It augments the coupling of the test with this implementation, version, etc
- 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.
Ok. But what if theJdbcTemplateis 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
add a comment |
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 :
- It complexify your test, potentially making it difficult to craft, read, understand or refactor
- You have to understand how is used this type.
- It augments the coupling of the test with this implementation, version, etc
- 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.
Ok. But what if theJdbcTemplateis 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
add a comment |
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 :
- It complexify your test, potentially making it difficult to craft, read, understand or refactor
- You have to understand how is used this type.
- It augments the coupling of the test with this implementation, version, etc
- 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.
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 :
- It complexify your test, potentially making it difficult to craft, read, understand or refactor
- You have to understand how is used this type.
- It augments the coupling of the test with this implementation, version, etc
- 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.
answered Jul 17 '13 at 9:24
BriceBrice
23.6k36781
23.6k36781
Ok. But what if theJdbcTemplateis 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
add a comment |
Ok. But what if theJdbcTemplateis 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
add a comment |
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.
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%2f17695056%2fmatching-jdbctemplate-update-method-with-mockito%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