Code coverage of Resultsetextractor anonymous class is not covered.
There is no excecption at run time , it is running fine.
We have mocked the jdbcTemplate using below sample code.
Mockito.when(mainTemplate.query(QUERY, new HashMap(),rs)).thenReturn(new Object());
Below Code (start with #Override annotation - extractData() method) is not covered after execution.
return mainTemplate.query(Query, paramMap, new ResultSetExtractor>() {
**#Override
public Map<String, Object> extractData(ResultSet resultSet)
throws SQLException, DataAccessException {
Map<String, Object> keyMap = new HashMap<String, Object>();
while (resultSet.next()) {
keyMap.put("key1",
resultSet.getString("data1"));
keyMap.put("key2", resultSet.getString("data2"));
}
return keyMap;
}**
});
Please help.
Please check sample code for your information.
**return jdbcTemplatre.query(Query, paramMap, new ResultSetExtractor<byte[]>() {
#Override
public byte[] extractData(ResultSet resultSet) throws SQLException,
DataAccessException {
byte[] data = null;
while (resultSet.next()) {
signature = resultSet.getBytes("data");
}
return data;
}
});**
Mockito.when(mainTemplate.query(Query, new HashMap<String,Object>(),rs)).thenAnswer(new Answer<Object>(){
#Override
public byte[] answer(InvocationOnMock invocationOnMock) throws Throwable {
ResultSetExtractor resultSetExtractor = invocationOnMock.getArgumentAt(2,ResultSetExtractor.class);
return (byte[]) resultSetExtractor.extractData(resSet);
}
});
The ResultSetExtractor code is not covered because it is never executed. And it is not executed because the mainTemplate.query call is mocked thus the ResultSetExtractor callback is never triggered.
You could triggered it while still using the mock by using Mockitos thenAnswer
Mockito.when(mainTemplate.query(QUERY, new HashMap(),rs)).thenAnswer(new Answer<Object>() {
#Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
ResultSetExtractor resultSetExtractor = invocationOnMock.getArgumentAt(2, ResultSetExtractor.class);
resultSetExtractor.extractData(...);
return new Object();
}
});
Or with java 8
Mockito.when(mainTemplate.query(QUERY, new HashMap(),rs)).thenAnswer(invocationOnMock -> {
ResultSetExtractor resultSetExtractor = invocationOnMock.getArgumentAt(2, ResultSetExtractor.class);
resultSetExtractor.extractData(...);
return new Object();
});
But testing this way you would have to create a ResultSet yourself.
But generally speaking: this way of calling resultSetExtractor.extractData in the mock might cause problems because it is making assumptions about how the jdbcTemplate.query method handles the ResultSetExtractor internally. But that behaviour might change and then your test does not represent anymore what actually happens in production.
Related
I would like to mock io.vertx.ext.jdbc.JDBCClient to unit-test the below verticle code:
class A {
private final Helper help = new Helper();
public JsonObject checkEmailAvailability(String email, JDBCClient jdbc) throws SignUpException {
JsonObject result = new JsonObject();
jdbc.getConnection(conn -> help.startTx(conn.result(), beginTans -> {
JsonArray emailParams = null;
emailParams = new JsonArray().add(email);
System.out.println(email);
help.queryWithParams(conn.result(), SQL_SELECT_USER_EMAIL, emailParams, res -> {
if (res.getNumRows() >= 1) {
result.put("message", "Email already registered");
}
});
}));
return result;
}
}
You can use Mockito to mock your jdbc behavior. Let's say you want to test how you verticle behave when res returns one row.
Mock your jdbc:
jdbc = Mockito.mock(JDBCClient.class);
Then you have to mock a ResultSet object:
ResultSet res = Mockito.mock(ResultSet.class);
Mockito.when(res.getNumRows()).thenReturn(1);
Then you have to mock the AsyncResult object who is in charge to return res:
AsyncResult<ResultSet> asyncResultResultSet = Mockito.mock(AsyncResult.class);
Mockito.when(asyncResultResultSet.succeeded()).thenReturn(true);
Mockito.when(asyncResultResultSet.result()).thenReturn(res);
Then you have to mock the SQLConnection object who is in charge to return asyncResultResultSet. Use Answer to grab the handler and force it to return your mock:
SQLConnection sqlConnection = Mockito.mock(SQLConnection.class);
Mockito.doAnswer(new Answer<AsyncResult<ResultSet>>() {
#Override
public AsyncResult<ResultSet> answer(InvocationOnMock arg0) throws Throwable {
((Handler<AsyncResult<ResultSet>>) arg0.getArgument(2)).handle(asyncResultResultSet);
return null;
}
}).when(sqlConnection).queryWithParams(Mockito.any(), Mockito.any(), Mockito.any());
Then you have to mock the AsyncResult object who is in charge to return the sqlConnection. Again, Answer helps:
AsyncResult<SQLConnection> sqlConnectionResult = Mockito.mock(AsyncResult.class);
Mockito.when(sqlConnectionResult.succeeded()).thenReturn(true);
Mockito.when(sqlConnectionResult.result()).thenReturn(sqlConnection);
Mockito.doAnswer(new Answer<AsyncResult<SQLConnection>>() {
#Override
public AsyncResult<SQLConnection> answer(InvocationOnMock arg0) throws Throwable {
((Handler<AsyncResult<SQLConnection>>) arg0.getArgument(0)).handle(sqlConnectionResult);
return null;
}
}).when(jdbc).getConnection(Mockito.any());
Here you are. It is a bunch of code but you can mock multiple ResultSet object and use them with the asyncResultResultSet by chaining multiple thenReturn:
Mockito.when(asyncResultResultSet.result()).thenReturn(res1).thenReturn(res2) ...;
Try not to test vertx.io.
Here is my complete solution if you want to find dependencies. I also use Powermock with VertxUnit to run my verticle.
To mock the JDBCClient in vertx using mockito ..add dependency testCompile "io.vertx:vertx-codegen:3.2.1"
Otherwise you will get error as . Cannot mock static
I am trying to write a unit test for a AWS SWF workflow. Below is the code I would like to Test
#Override
public void execute(String abc) {
new TryCatch() {
#Override
protected void doTry() throws Throwable {
Promise<SomeObject> temp = activityClient.action(abc);
again(temp, abc);
}
#Override
protected void doCatch(Throwable e) throws Throwable {
throw new RuntimeException(e);
}
};
}
#Asynchronous
public void again(Promise<SomeObject> someObject, String abc) {
// Do Something
}
My Test class is as below:
public class SomeWorkflowTest extends AbstractTestCase {
#Rule
public WorkflowTest workflowTest = new WorkflowTest();
List<String> trace;
private SomeWorkflowClientFactory workflowFactory = new SomeWorkflowClientFactoryImpl();
#Before
public void setUp() throws Exception {
trace = new ArrayList<String>();
// Register activity implementation to be used during test run
SomeActivitiesImpl activitiesImpl = new SomeActivitiesImpl() {
#Override
public SomeObject performHostRecovery(String abc) {
trace.add("ABC: " + abc);
SomeObject testObject = new SomeObject();
return testObject;
}
};
workflowTest.addActivitiesImplementation(activitiesImpl);
workflowTest.addWorkflowImplementationType(SomeWorkflowImpl.class);
}
#Test
public void testWorkflowExecutionCall() throws Throwable {
SomeWorkflowClient workflow = workflowFactory.getClient("XZY");
workflow.execute("XYZ");
List<String> expected = new ArrayList<String>();
expected.add("ABC: abc");
AsyncAssert.assertEqualsWaitFor("Wrong Wrong", expected, trace, null);
}
}
I have used SWF Testing Docs to write above test class. However the method that I am testing (execute()) is invoking another method in same class. I am not concerned with the execution of internal method and would like to mock it out, but given the way the workflow class object is instantiated, I am not clear on how to mock the inner method.
Can someone please point out on this?
Thanks
You actually can instantiate a workflow object or any other object that workflow uses inside the test method:
#Test
public void testWorkflowExecutionCall() throws Throwable {
SomeWorkflow workflow = new SimpleWorkflow(...);
workflow.execute("XYZ");
List<String> expected = new ArrayList<String>();
expected.add("ABC: abc");
AsyncAssert.assertEqualsWaitFor("Wrong Wrong", expected, trace, null);
}
It works because WorkflowTest executes test methods in the context of a dummy test workflow. The code
SomeWorkflowClient workflow = workflowFactory.getClient("XZY");
workflow.execute("XYZ");
actually creates a child workflow in the context of this dummy workflow. But nothing prevents you from executing any async code directly without creating the child workflow.
There is a method public Content createChild(String path, String contentType, Map<String,Object> properties) I'd like to mock.
I want to mock it that way that the method is called with any kind of arguments, therefore when() wouldn't work because I have to tell it what arguments the method should receive to be actually mocked.
So I want to actually react on any method call independent of its given arguments (use spies?) and then call some kind of "callback" to return a Content object which I want build together out of the real arguments given to the method.
I could not find a specific API in Mockito which supports this.
You can use Matchers:
You can try something like:
when(service.createChild(anyString(), anyString(), anyMap()))
.thenReturn(any(Content.class));
Sure you can. I have written simple unit test for this
public class MockitoTest {
private SampleService sampleService;
#Before
public void setUp() throws Exception {
sampleService = Mockito.mock(SampleService.class);
}
#Test
public void mockitoTest() throws Exception {
when(sampleService.createChild(anyString(), anyString(), anyMapOf(String.class, Object.class)))
.thenAnswer(invocationOnMock -> {
//Here you can build result based on params
String pathArg = (String) invocationOnMock.getArguments()[0];
if (pathArg.equals("p1")) {
return new Content("Content for p1");
} else if (pathArg.equals("p2")) {
return new Content("Content for p2");
} else {
return invocationOnMock.callRealMethod();
}
});
Content content = sampleService.createChild("p1", "any", new HashMap<>());
assertEquals("Content for p1", content.getData());
content = sampleService.createChild("p2", "any", new HashMap<>());
assertEquals("Content for p2", content.getData());
content = sampleService.createChild("whatever", "any", new HashMap<>());
assertEquals("original", content.getData());
}
/**
* Sample service with method
*/
private static class SampleService {
public Content createChild(String path, String contentType, Map<String, Object> properties) {
return new Content("original");
}
}
/**
* Content example
*/
private static class Content {
private String data;
Content(String data) {
this.data = data;
}
String getData() {
return data;
}
}
}
You can use matchers
MyClass m = mock(MyClass.class);
when(m.createChild(any(String.class), any(String.class), any(Map.class))).thenReturn(new Content());
You should also be able to use the parameters this way
when(m.createChild(any(String.class), any(String.class), any(Map.class))).thenAnswer(
new Answer<Content>()
{
#Override
public Content answer(final InvocationOnMock invocation) throws Throwable
{
return new Content((String) invocation.getArguments()[0],
(String) invocation.getArguments()[1],
(Map) invocation.getArguments()[2]);
}
}
}
);
You can try something like with use of eq() and any() as per as your requirement:
when(service.createChild(eq("helloe/hi"), any(String.class), any(Map.class)))
.thenReturn(any(Content.class));
eq - If we want to use a specific value for an argument, then we can use eq() method.
any - Sometimes we want to mock the behavior for any argument of the given type
I have a JAVA rest service that interacts with the database , does some manipulation and returns the data.
I am trying to write test cases for these APIs.
I am trying to use the below link for reference to implement this.
http://www.developer.com/java/other/article.php/10936_3882311_2/Mockito-Java-Unit-Testing-with-Mock-Objects.htm
Here, calls made to the database are suppressed and the dto is mocked with made up values.
Is there an alternate method where we actually get to run the queries w/o talking to the db , (an in-memory db may be? )
Any code sample or reference would be of great help.
For a pure HashMap solution, something like this would work though then you would loose access to SQL query functionality (unless you mock the query too).
public class MockDatabase<T> {
protected Map<Serializable, T> fakeDatabase = Maps.newHashMap();
private final CustomRepository<T,Serializable> repository;
private Validator validator;
public void setValidator(Validator validator) {
this.validator = validator;
}
public static <T extends CustomRepository> T mock(Class<T> classToMock, Validator validator) {
T repository = Mockito.mock(classToMock);
MockDatabase md = new MockDatabase<T>(repository, validator);
return repository;
}
public <ID extends Serializable> MockDatabase(CustomRepository<T, ID> repository, Validator validator){
this.repository = (CustomRepository<T, Serializable>) repository;
this.validator = validator;
reset(repository);
doAnswer(new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
fakeDatabase.clear();
return null;
}
}).when(repository).deleteAll();
when(repository.save((T) anyObject())).thenAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return saveOrSaveAndFlush(invocation);
}
});
when(repository.getReference((ID)anyObject())).thenAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return fakeDatabase.get(invocation.getArguments()[0]);
}
});
when(repository.findOne((ID)anyObject())).thenAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return fakeDatabase.get(invocation.getArguments()[0]);
}
});
doAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return fakeDatabase.remove(ReflectionTestUtils.invokeGetterMethod(invocation.getArguments()[0], "getId"));
}
}).when(repository).delete((T)anyObject());
doAnswer(new Answer<ID>() {
#Override
public ID answer(InvocationOnMock invocation) throws Throwable {
fakeDatabase.remove(((ID)invocation.getArguments()[0]));
return null;
}
}).when(repository).delete((ID)anyObject());
when(repository.saveAndFlush((T) anyObject())).thenAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return saveOrSaveAndFlush(invocation);
}
});
when(repository.exists((ID)anyObject())).thenAnswer(new Answer<Boolean>() {
#Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
return fakeDatabase.containsKey(invocation.getArguments()[0]);
}
});
when(repository.merge(anyObject())).thenAnswer(new Answer<T>() {
#Override
public T answer(InvocationOnMock invocation) throws Throwable {
return (T) invocation.getArguments()[0];
}
});
when(repository.findAll()).thenAnswer(new Answer<List<T>>() {
#Override
public List<T> answer(InvocationOnMock invocation) throws Throwable {
return Lists.newLinkedList(fakeDatabase.values());
}
});
customMethods();
}
private T saveOrSaveAndFlush(InvocationOnMock invocation) throws NoSuchMethodException {
Object[] args = invocation.getArguments();
Serializable id = (Serializable) ReflectionTestUtils.getField(args[0], "id");
if (id == null) {
Class<?> returnType = args[0].getClass().getMethod("getId").getReturnType();
if (returnType.equals(Long.class)) {
id = (Long) new Random().nextLong();
} else if (returnType.equals(Integer.class)) {
id = (Integer) new Random().nextInt();
}
ReflectionTestUtils.setField(args[0], "id", id);
}
Set<ConstraintViolation<T>> validations = validator.validate((T)args[0]);
if (!validations.isEmpty()){
throw new IllegalStateException("Object failed validations (it would also fail on a db): "+validations);
}
for (Method method: args[0].getClass().getDeclaredMethods()){
if (method.isAnnotationPresent(Basic.class)){
Annotation a = method.getAnnotation(Basic.class);
if (!(boolean) AnnotationUtils.getValue(method.getAnnotation(Basic.class), "optional")){
if (ReflectionTestUtils.invokeGetterMethod(args[0], method.getName()) == null){
throw new IllegalStateException(args[0].getClass().getSimpleName()+"."+method.getName() + " returned null, but marked with #Basic(optional=false) - it would also fail on a db: "+validations);
}
}
}
}
fakeDatabase.put(id, (T) args[0]);
return (T) args[0];
}
public void customMethods() {
// override here if you want
}
}
If you had #Entity annotated POJOs, then with say hibernate library you can ask it to export to HSQLDB script and then use that. Eg you export via:
Configuration configuration = new Configuration();
try {
classes().forEach(cl -> {
configuration.addAnnotatedClass(cl);
});
configuration.setProperty("hibernate.dialect", HSQLCustomDialect.class.getName());
SchemaExport schemaExport = new SchemaExport(configuration);
schemaExport.setOutputFile("someFileName.sql");
schemaExport.setFormat(false);
schemaExport.setDelimiter(";");
schemaExport.execute(true, false, false, true);
and thereafter you would use spring to insert that SQL script for you:
#ActiveProfiles("test")
#SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)
#SqlGroup({
#Sql(statements = "DROP SCHEMA PUBLIC CASCADE"),
#Sql(scripts = "classpath:yourGeneratedSQL.sql"),
})
public class DAOIntegrationTest {
HSQLDB is one in memory db i'm familiar with. The examples showed here against HSQLDB used with hibernate and JPA. http://uaihebert.com/tdd-with-hsqldb-jpa-and-hibernate/.
However i think it'll be useful to ask why you would prefer connecting to an in memory db than mocking the db in your situation?
It boils down to what scope of testing unit/integration you are trying to achieve.
What are you trying to test the manupilation logic in the rest layer? Where mocking is sufficient.
Are you trying to test how the rest handles the data access behavior, such as db error handling etc, than in memory might be slightly better.
Is the thing you are testing dependent on data setup/ testing data setup , in which case in memory db might be closer, since you can use the same/similar sql creation to test in inmemory db.
Consider a method signature like:
public String myFunction(String abc);
Can Mockito help return the same string that the method received?
Since Mockito 1.9.5+ and Java 8+
You can use a lambda expression, like:
when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);
Where i is an instance of InvocationOnMock.
For older versions
You can create an Answer in Mockito. Let's assume, we have an interface named MyInterface with a method myFunction.
public interface MyInterface {
public String myFunction(String abc);
}
Here is the test method with a Mockito answer:
public void testMyFunction() throws Exception {
MyInterface mock = mock(MyInterface.class);
when(mock.myFunction(anyString())).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return (String) args[0];
}
});
assertEquals("someString",mock.myFunction("someString"));
assertEquals("anotherString",mock.myFunction("anotherString"));
}
If you have Mockito 1.9.5 or higher, there is a new static method that can make the Answer object for you. You need to write something like
import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
when(myMock.myFunction(anyString())).then(returnsFirstArg());
or alternatively
doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());
Note that the returnsFirstArg() method is static in the AdditionalAnswers class, which is new to Mockito 1.9.5; so you'll need the right static import.
With Java 8 it is possible to create a one-line answer even with older version of Mockito:
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
Of course this is not as useful as using AdditionalAnswers suggested by David Wallace, but might be useful if you want to transform argument "on the fly".
I had a very similar problem. The goal was to mock a service that persists Objects and can return them by their name. The service looks like this:
public class RoomService {
public Room findByName(String roomName) {...}
public void persist(Room room) {...}
}
The service mock uses a map to store the Room instances.
RoomService roomService = mock(RoomService.class);
final Map<String, Room> roomMap = new HashMap<String, Room>();
// mock for method persist
doAnswer(new Answer<Void>() {
#Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 0 && arguments[0] != null) {
Room room = (Room) arguments[0];
roomMap.put(room.getName(), room);
}
return null;
}
}).when(roomService).persist(any(Room.class));
// mock for method findByName
when(roomService.findByName(anyString())).thenAnswer(new Answer<Room>() {
#Override
public Room answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 0 && arguments[0] != null) {
String key = (String) arguments[0];
if (roomMap.containsKey(key)) {
return roomMap.get(key);
}
}
return null;
}
});
We can now run our tests on this mock. For example:
String name = "room";
Room room = new Room(name);
roomService.persist(room);
assertThat(roomService.findByName(name), equalTo(room));
assertNull(roomService.findByName("none"));
With Java 8, Steve's answer can become
public void testMyFunction() throws Exception {
Application mock = mock(Application.class);
when(mock.myFunction(anyString())).thenAnswer(
invocation -> {
Object[] args = invocation.getArguments();
return args[0];
});
assertEquals("someString", mock.myFunction("someString"));
assertEquals("anotherString", mock.myFunction("anotherString"));
}
EDIT: Even shorter:
public void testMyFunction() throws Exception {
Application mock = mock(Application.class);
when(mock.myFunction(anyString())).thenAnswer(
invocation -> invocation.getArgument(0));
assertEquals("someString", mock.myFunction("someString"));
assertEquals("anotherString", mock.myFunction("anotherString"));
}
This is a pretty old question but i think still relevant. Also the accepted answer works only for String. Meanwhile there is Mockito 2.1 and some imports have changed, so i would like to share my current answer:
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
#Mock
private MyClass myClass;
// this will return anything you pass, but it's pretty unrealistic
when(myClass.myFunction(any())).then(returnsFirstArg());
// it is more "life-like" to accept only the right type
when(myClass.myFunction(any(ClassOfArgument.class))).then(returnsFirstArg());
The myClass.myFunction would look like:
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
You can achieve this by using ArgumentCaptor
Imagine you have bean function like so.
public interface Application {
public String myFunction(String abc);
}
Then in your test class:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation) throws Throwable {
return param.getValue();//return the captured value.
}
});
OR if you fan of lambda simply do:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture()))
.thenAnswer((invocation) -> param.getValue());
Summary: Use argumentcaptor, to capture the parameter passed. Later in answer return the value captured using getValue.
This is a bit old, but I came here because I had the same issue. I'm using JUnit but this time in a Kotlin app with mockk. I'm posting a sample here for reference and comparison with the Java counterpart:
#Test
fun demo() {
// mock a sample function
val aMock: (String) -> (String) = mockk()
// make it return the same as the argument on every invocation
every {
aMock.invoke(any())
} answers {
firstArg()
}
// test it
assertEquals("senko", aMock.invoke("senko"))
assertEquals("senko1", aMock.invoke("senko1"))
assertNotEquals("not a senko", aMock.invoke("senko"))
}
You might want to use verify() in combination with the ArgumentCaptor to assure execution in the test and the ArgumentCaptor to evaluate the arguments:
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
The argument's value is obviously accessible via the argument.getValue() for further manipulation / checking /whatever.
I use something similar (basically it's the same approach). Sometimes it's useful to have a mock object return pre-defined output for certain inputs. That goes like this:
private Hashtable<InputObject, OutputObject> table = new Hashtable<InputObject, OutputObject>();
table.put(input1, ouput1);
table.put(input2, ouput2);
...
when(mockObject.method(any(InputObject.class))).thenAnswer(
new Answer<OutputObject>()
{
#Override
public OutputObject answer(final InvocationOnMock invocation) throws Throwable
{
InputObject input = (InputObject) invocation.getArguments()[0];
if (table.containsKey(input))
{
return table.get(input);
}
else
{
return null; // alternatively, you could throw an exception
}
}
}
);