【问题标题】:Mockito is not mocking the object instead its calling the method inside the objectMockito 不是在模拟对象,而是在对象内部调用方法
【发布时间】:2018-12-29 03:48:07
【问题描述】:

我正在研究 java 项目,其中我有一个名为 user 的类,它将用户的详细信息存储在数据库中。我正在尝试使用测试用例测试这个类:当用户成功创建表时,我创建了一个返回“用户创建”的字符串,我想使用 junit 进行测试。下面是我的junit测试代码

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());
	}

}

现在我想模拟我从其他类中使用的对象,例如“iterationDetails.getUserId()”。当我尝试模拟对象而不是被模拟时,它正在调用真正的方法 getuserId() 并返回 null。我该如何解决这个问题?下面是我的用户创建类。

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;博士

在这种情况下我应该如何模拟对象?

【问题讨论】:

    标签: java junit mockito


    【解决方案1】:

    您正在模拟的dbConnection 永远不会传递到您的其他方法中。而是使用 DatabaseConnection.getInstance() 返回的任何连接。

    您应该考虑重构您的方法,以便通过依赖注入而不是静态访问器提供连接。然后你的测试可以注入模拟而不是真正的连接。

    【讨论】:

    • 感谢您的回复。 dbConnection 类是一个单例,我将更改此方法,但问题是我在 iterationDetails.getUserId() 处获得空指针期望。因为我在 getuserid 中调用了一个方法,该方法接受静态对象并将其转换为字符串并返回它。现在当这个方法被触发时,静态对象将为空,所以我的代码失败了。
    • 看起来和IterationDetailsParser.getInstance()有类似的交易
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您应该为类依赖项使用参数化构造函数。这将适用于 Spring 或任何 POJO。使用此方法,您可以轻松地模拟测试类中的依赖项。

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

      如果您正在使用 Spring,请阅读以下内容: https://www.baeldung.com/constructor-injection-in-spring

      Spring @Autowire on Properties vs Constructor

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-28
        • 2017-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多