【问题标题】:Mocking JDBC's Connection#prepareStatement always returns null with jMockit使用 jMockit 模拟 JDBC 的 Connection#prepareStatement 始终返回 null
【发布时间】:2016-04-30 03:00:05
【问题描述】:

我正在尝试使用 jMockit 测试对 Oracle DB 的 JDBC 调用。我试图模拟 JDBC 的 Connection#prepareStatement(String sql) 以返回 PreparedStatement 模拟对象,但我只得到一个空值。我的目标是模拟 Connection API 以返回模拟 PreparedStatement 对象,并模拟 PreparedStatement API 以返回模拟 ResultSet 对象。

我的源代码如下。

try (Connection conn = DriverManager.getConnection(url, username, password);) {
  try(PreparedStatement ps = conn.prepareStatement(
         "SELECT firstName, lastName from Employee where empId = ?");) {
    ps.setString(1, empId); // This is an input to function.
    try(ResultSet rs = ps.executeQuery();) {
      while(rs.next()) {
        Employee emp = new Employee();
        emp.setFirstName(rs.getString("firstName"));
        emp.setLastName(rs.getString("lastName"));
        return emp;
      }
    }
  }
}
return employees;

当我调用时

PreparedStatement ps = conn.prepareStatement(
             "SELECT firstName, lastName from Employee where empId = ?")

我的单元测试如下

@Test()
  public void testQueryOutOfDateSpanishContent_Success(
      @Mocked final Connection connection, @Mocked final PreparedStatement ps) throws Exception {
    new Expectations(DriverManager.class) {
      {
        DriverManager.getConnection(
            dcrParameters.getEnvironmentUrl(), dcrParameters.getUsername(),
            dcrParameters.getPassword());
        result = connection;

        connection.prepareStatement(anyString);
        result = with(new Delegate<PreparedStatement>() {
          public PreparedStatement prepareStatement(String sql) throws SQLException {
            return ps;
          }
        });
      }
    };
    // Call the source function here.

我正在使用带有最新版本 jMockit 的 TestNG 6.10。我正在使用 TestNG eclipse 插件运行单元测试。我在 Eclipse 中将 -javaagent:C:\downloads\jmockit.jar 作为 VM 参数传递。

更新:该方法接受 jMockit 提供的两个模拟参数。如果我没有通过 java 代理,TestNG 会抛出一个错误,期望通过 TestNG 的 dataProvider 功能传递参数。 http://testng.org/doc/documentation-main.html#parameters-dataproviders

它确实返回了一个模拟对象,但它采用了默认行为。例如,我想捕获传递给ps.setString(1, empId) 的值或模拟rs.next() 以返回true。但只返回默认输出。

【问题讨论】:

  • 执行过程中没有异常?我认为您应该使用Catch 块并尝试打印stackTrace 这种情况必须抛出异常。谢谢
  • Connection#prepareStatement 不会抛出任何异常。该值始终为空。下一条语句 ps.setString(1, empId);抛出 NPE。所以问题是返回了空值。
  • 如果Delegate 只是返回ps,为什么还要使用它?只需将其直接用作所需的result,就像对connection 所做的那样。请注意,with(...) 之类的方法用于参数匹配,而不是用于预期结果。
  • 另外,不需要指定-javaagentJVM参数。
  • @Rogério 我已尝试在问题的更新部分回答您的问题。谢谢!

标签: java unit-testing jdbc testng jmockit


【解决方案1】:

这不是错误。这是一个功能:)

您需要配置模拟。默认情况下,它们将返回 null。

你需要添加'Expectation'-s,你可以在http://jmockit.org/tutorial/Mocking.html看到

【讨论】:

  • 我已经做到了。正在创建模拟,但除非我设置两个单独的期望块,否则它不会被传递。
  • 这是一个危险的链接。请不要点击它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 2015-08-15
  • 2012-03-18
  • 2016-11-04
相关资源
最近更新 更多