简体   繁体   中英

Mockito is not mocking the object instead its calling the method inside the object

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?

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.

您不能使用Mockito模拟静态方法,应该在Mockito之上使用PowerMockito'PowerMockito.mockStatic模拟静态方法。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM