为junit覆盖模拟oracle STRUCT类

时间:2016-07-23 13:54:32

标签: java junit mockito powermockito

在我的项目中,我需要在oracle中调用存储过程。此过程接受我创建的对象类型的自定义表。在java方面,我已经创建了实现的类型处理程序并处理了将数组类型数据传递给过程。

从编码的角度来看,一切正常:)

现在我需要为我创建的处理程序类编写junits。这个处理程序调用我的util类来获取StructDescriptor,STRUCT对象。以下是实用程序类代码段。

Class JDBCUtil {
    public static STRUCT getJDBCDataObject(final StructDescriptor structDescriptor, final Connection con,
      final Object[] params) {
    STRUCT struct = null;
    try {
      struct = new STRUCT(structDescriptor, con, params);
    } catch (SQLException e) {
    }
    return struct;
  }
}

我的maven依赖项中有Mockito和PowerMockito库。以下是我的测试课程。

@SuppressWarnings({"unchecked", "unused"})
@RunWith(PowerMockRunner.class)
@PrepareForTest({ StructDescriptor.class, ArrayDescriptor.class, STRUCT.class })
public class JDBCUtil Test {

  private JDBCUtil jdbcUtil;

  @Mock
  private OracleConnection connection;

  @Mock
  private StructDescriptor structDescriptor;

  @Mock
  private STRUCT struct;


  @Before
  public void test() {
    MockitoAnnotations.initMocks(this);
    jdbcUtil = new JDBCUtil();


    Mockito.when(connection.isLogicalConnection()).thenReturn(false);
  }

  @Test
  public void testShouldReturnValidJDBCTypeStructureObject() {
    Object[] objs = new Object[1];
    objs[0] = Mockito.mock(Object.class);
    try {
      //Mockito.when(new STRUCT(structDescriptor, connection,     objs)).thenReturn(struct);
      PowerMockito.whenNew(STRUCT.class).withArguments(structDescriptor, connection, objs).thenReturn(struct);
    } catch (SQLException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
    STRUCT structObj = JDBCProcedureTypeDescriptor.getJDBCDataObject(structDescriptor, connection, objs);
    Assert.assertNotNull(structObj);
  }


}

我正在尝试模拟在我的类中创建STRUCT的对象,但我的代码总是尝试创建对象并失败,因为连接等是模拟对象,它在 STRUCT< init()&gt中给出空指针;(STRUCT.java:138)

虽然当我在 @PrepareForTest 注释中添加 JDBCUtil 时,测试用例会成功执行,但eclipse根本不会显示该类。

有没有办法可以模拟STRUCT对象的创建并以100%覆盖我的方法。

1 个答案:

答案 0 :(得分:0)

问题:你是否开始使用Powermock,因为你有充分的理由,或者更巧合的理由?

你知道 - 问题出在你的代码中。它只是以 untestable 方式编写。并且惊讶:它的编写方式,也会影响每个客户的可测试性。想要使用这种方法。

关键问题是:您在这里使用静态;没有必要这样做。什么阻止你将你的JdbcUtils重命名为" STRUCTFactory"例如?然后,您只需创建一个普通的实例方法,而不是在那里使用静态方法。突然之间,您不再需要PowerMock来进行静态调用。如果你担心效率(在这一点上你不应该这样做);你仍然可以使用单例并附加一个STRUCTFactory接口。

接下来 - 为什么要使用模拟框架来检查对new的调用?实质上,您正在测试实现细节。编写一个简单调用工厂方法(使用不同参数)的测试会更简单,然后对返回给你的STRUCT对象执行 assertXyz 调用。

意义:

  1. 静态是良好OO设计的异常;避免它有很多方面的帮助;使用它迫使你转向PowerMock。
  2. 您不必测试操作本身,检查操作结果是否具有预期属性是完全公平的!
  3. 长话短说:使用PowerMock的理由很少;许多人不这样做(你所面临的覆盖问题就是其中之一)。但是你的代码可以很容易地重做,这样你就可以用Mokito完全测试它 - 除此之外不需要超级 power 。只需遵循一些已知良好的简单规则" OO设计"首先是实践。

    如果您对"如何创建可测试的"感兴趣?代码...你可以转here