使用 Java/Mockito/PowerMockito 实例化具有私有构造函数的类

4 java junit mockito powermockito

我正在编写一个测试用例,被测JUnit方法采用一个带有私有构造函数作为参数的最终类。由于我无法new使用我尝试使用的关键字实例化它,Mockito但发现Mockito它不喜欢final class. 我去使用PowerMockito这对我来说似乎合理但它PowerMockito.mockStatic(Field.class);是一个无效的方法,我需要一个引用,Field以便我可以在调用该方法时将它作为参数传递。

我想赶上,IllegalArgumentException但首先我需要将引用Field作为参数传递

测试方法

public boolean accept(Field field) { 
    if( ignoreNulls ) {
        try {
            if( field.get( super.getObject() ) == null ) {
                return false;
            }
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }

    return super.accept(field); 
} 
Run Code Online (Sandbox Code Playgroud)

JUnit 测试用例

   @Test(expected=IllegalArgumentException.class)
    public void testAccept() throws Exception {
      DefaultToStringBuilder builder = new DefaultToStringBuilder(new Object());
      PowerMockito.mockStatic(Field.class);

      builder.accept(?);
}
Run Code Online (Sandbox Code Playgroud)

我不知道我该怎么做。

提前致谢

小智 5

我们实际上可以使用它Core Java来实现这一点。下面的代码显示了如何做到这一点。

    private Field field;

    @Test(expected=IllegalArgumentException.class)
    public void testAccept() throws Exception {
      Class<?> clazz = Field.class;
      Constructor<?> [] constructors = clazz.getDeclaredConstructors();

      for(Constructor cons: constructors) {
          cons.setAccessible(true);
          field = (Field) cons.newInstance();
      }

      DefaultToStringBuilder builder = new DefaultToStringBuilder(new Object());
      builder.accept(field);

      assertNotNull(builder);
    }
Run Code Online (Sandbox Code Playgroud)


Gho*_*ica 5

我的回答不会那样做。不要仅仅因为您的生产代码无法通过其他方式测试而参与 PowerMock。

您很快就会发现 PowerMock 会产生比它解决的更多的问题。

通常,使用 PowerMock 的需要来自一个损坏的设计。因此,与其花费数小时通过 PowerMock 启用损坏的设计以进行测试……您最好花一小部分时间来重新设计您的设计。(根据我的一次经验:PowerMock 很快就会导致花费在它上面的时间不计其数)

意思是:您可以添加一个包保护的构造函数以进行测试。或者,您可能会更进一步以了解更广泛的情况;并找到允许公共构造函数的方法;同时保持导致当前最终/私人实施的设计理念。