0

I am working on java project where I have a class called user which stores the details of the user in the database. I am trying to test this class using testcase: When user succesfully create table, I have created a string which will return "user created ", I want to test this using junit . Below is my code for junit test

public class UserDatabaseTest 
{
 
    User user = null;
    IterationDetailsParser iterationDetails = mock(IterationDetailsParser.class);
    DatabaseConnection  dbConnection = mock(DatabaseConnection.class);
    Object obj ;
    Connection con;
 @Before
 public void setUp() throws SQLException 
 {
   MockitoAnnotations.initMocks(this);
     user = new User();
    con = (Connection) dbConnection.GetDBConnection();
    obj =  iterationDetails.getUserId();
 }
 
 @Test
 public void test() throws JsonProcessingException, SQLException 
 {
  

 

  Mockito.when(dbConnection.GetDBConnection()).thenReturn(con);
  
  Mockito.when(iterationDetails.getUserId()).thenReturn("8");
  assertSame("User ID alreday exits", user.CreateUserDetails());
 }

}

Now I want to mock objects such as "iterationDetails.getUserId()" which I am consuming from other class . When I try to mock the object instead of being mocked, it is calling the real method getuserId() and returning null. How can I resolve this ? Below is my usercreationclass.

public String CreateUserDetails() throws SQLException, JsonProcessingException 
 {
  dbcon = DatabaseConnection.getInstance();
  iteratinDetails = IterationDetailsParser.getInstance();
   String st;

  try {

   String sqlUser = "INSERT INTO user (User_Id,Username,Active_Indi)VALUES(?,?,?)";
   PreparedStatement statement = (PreparedStatement) dbcon.GetDBConnection().prepareStatement(sqlUser);
   statement.setString(1, iteratinDetails.getUserId());
   statement.setString(2, iteratinDetails.getUserObj());
   statement.setBoolean(3, true );
   
   statement.executeUpdate();
   statement.close();
   System.out.println("user created");
      
      // string i return in last compare using assertEquals
   st = "user created";
      
  } catch (SQLException e) 
  {
   System.out.println("user id alredy exits");
   userIdExits = false;
  
  }
  
  return st;
 }

tl;dr

How should I mock the objects in this condition?

KumarAnkit
  • 713
  • 1
  • 9
  • 26
Divakar R
  • 81
  • 5
  • 12

3 Answers3

0

The dbConnection you are mocking is never passed into your other method. It is instead using whichever connection is being returned by DatabaseConnection.getInstance().

You should consider refactoring your method so that the connection is provided by dependency injection rather than static accessor. Then your test can inject the mock rather than the real connection.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • Thanks for the reply. dbConnection class is a singleton, i will change this method but the problem is i am getting null pointer expectation at iterationDetails.getUserId(). because i am calling a method inside getuserid which acpetes static object and convert it to string and return it . now when this method is triggers static object will be null so my code is getting failed. – Divakar R Dec 28 '18 at 01:24
  • Looks like a similar deal with `IterationDetailsParser.getInstance()` – Joe C Dec 28 '18 at 01:26
0

you can't mock static methods using Mockito, you should use PowerMockito'PowerMockito.mockStatic on top of Mockito to mock static methods.

DEVAS
  • 344
  • 2
  • 12
0

You should use a parameterized constructor for class dependencies. This will work with a Spring or any POJO. Using this method you can easily mock dependencies in your test class.

public class ParentClass{

private DBConnection dbcon;
 public ParentClass(DBConnection dbcon){
  this.dbcon = dbcon;
 }
 public String CreateUserDetails(){...} // get rid of dbcon = DatabaseConnection.getInstance();
}

Here is a useful read if you are using Spring: https://www.baeldung.com/constructor-injection-in-spring

Spring @Autowire on Properties vs Constructor

Phil Ninan
  • 1,108
  • 1
  • 14
  • 23