0

Here is my method under test as well as test code. My method under test depends on the result set produced by runExecuteQueryStatement. If the resultSet is null and resultSet.next is false it is going to return 0 else when the resultSet.next returns something, then it will return 1. That's reason I mocked ResultSet, ResultSet.next(). But still I'm getting 0 as a return value. Any help will be much appreciated. Thanks

Method Under Test

int result = 0;

    try {
        ResultSet resultSet = runExecuteQueryStatement(dbServerConn, "SELECT 1 AS cnt FROM pg_database WHERE datname ='" + dbName + "';");
        while (resultSet.next()) {
            result = resultSet.getInt("cnt");
        }
    }catch(Exception ex) {
        logger.error(ex.getMessage());
    }

    return result;

Dependent Method Code (runExecuteQueryStatement)

ResultSet resultSet = null;
    Connection conn = getConnection(dbServerConn);
    Statement stmt = conn.createStatement();
    resultSet = stmt.executeQuery(sqlStatement);

    return resultSet;

Test Code

PostgresDatabaseManager pgManagerMock = Mockito.mock(PostgresDatabaseManager.class);
    DbConnection dbConnectionMock = Mockito.mock(DbConnection.class);

    String sqlStatementMock = SOME_STRING;

    ResultSet resultSetMock = Mockito.mock(ResultSet.class);
    Mockito.when(resultSetMock.next()).thenReturn(TRUE).thenReturn(FALSE);
    Mockito.when(resultSetMock.getInt("cnt")).thenReturn(1);

    Mockito.when(pgManagerMock.runExecuteQueryStatement(dbConnectionMock, sqlStatementMock)).thenReturn(resultSetMock);

    Mockito.when(pgManagerMock.runExecuteQueryStatementWrapperForCheckDBExists(dbConnectionMock, sqlStatementMock)).thenCallRealMethod();

    int actualResult = pgManagerMock.runExecuteQueryStatementWrapperForCheckDBExists(dbConnectionMock, sqlStatementMock);

    int expectedResult = 1;

    Assert.assertEquals(expectedResult, actualResult);
Muthaiah PL
  • 1,048
  • 3
  • 15
  • 26
  • what is the content of `runExecuteQueryStatement` method? – Klaimmore Mar 01 '18 at 21:41
  • @Klaimmore I have edited my question to add the code snippet for #runExecuteQueryStatement# – Muthaiah PL Mar 01 '18 at 22:01
  • the code is still incomplete, my guess is that in `getConnection(dbServerConn)` you do not return a mocked `Connection`, and therefore when you do `stmt.executeQuery(sqlStatement)` you're not really using your `resultSetMock`. You may be able to debug the test and check for the actual runtime types of those objects – Klaimmore Mar 01 '18 at 22:08
  • When I test MethodA which is depends on MethodB. I just need to mock just MethodB correct? I don't need to Mock the methods which MethodB depends on. In that case, I'm testing a method which depends on runExecuteQueryStatement, So, I mocked that, but I didn't mocked getConnection on which runExecuteQueryStatement is depending on – Muthaiah PL Mar 01 '18 at 22:16
  • actually, you need to mock the object dependencies and their called methods, not just methods. Otherwise, the real implementations are going to get called. – Klaimmore Mar 02 '18 at 00:44

1 Answers1

0

Argument Matching is the problem. The dependent method runExecuteQueryStatement have 2 arguments where one is an object and the other is a string. Object can be mocked, where as the string is hardcoded. But in the implementation, I passed a different string as a parameter for the same method, so the stubbing didn't work. Instead of hardcoding the string value in stubbing, we should do argument matching by Matchers.anyString(). When we use Matchers for argument matching for a method. All the arguments on that method should Matchers. So, the stubbing work with all different argument values.

Mockito.when(pgManagerMock.runExecuteQueryStatement(Matchers.anyObject(), Matchers.anyString())).thenReturn(resultSetMock);
Muthaiah PL
  • 1,048
  • 3
  • 15
  • 26