Java 使用EasyMock和PowerMock捕获私有方法参数

Java 使用EasyMock和PowerMock捕获私有方法参数,java,capture,easymock,powermock,private-methods,Java,Capture,Easymock,Powermock,Private Methods,对于公共方法调用,EasyMock的capture()允许您截取和检查传递给该方法的参数。对于私有方法调用,PowerMock的expectPrivate允许您模拟私有方法调用 有没有一种方法可以以某种方式组合这些参数并将参数传递给私有方法调用?例如: public class Program { public FancyReturnType PublicMethod() { ArbitraryType localInstance = new ArbitraryT

对于公共方法调用,EasyMock的capture()允许您截取和检查传递给该方法的参数。对于私有方法调用,PowerMock的expectPrivate允许您模拟私有方法调用

有没有一种方法可以以某种方式组合这些参数并将参数传递给私有方法调用?例如:

public class Program
{
    public FancyReturnType PublicMethod()
    {
        ArbitraryType localInstance = new ArbitraryType();
        localInstance.setFoo(somePrivateHelperMethod());
        localInstance.setBar(increasinglyComplexMagic());

        long aLongValue  = 11235L;
        // more variables, more work

        SomeType worker = privateHelperToIntercept(localInstance, aLongValue, otherVariables);

        if (worker.something)
        {
            return retVal.aFancyReturnType;
        }
        else
        {
            return retVal.anotherFancyReturnType;
        }
    }
}
在本例中,我想检查
localInstance
对象,因为它被
privateHelperPointercept()
调用使用

我发现了大量模拟私有方法调用的示例;PowerMock的
expectPrivate(partiallyMockedObject,“nameOfPrivateMethod”,arg1,arg2)
非常有效。我还发现了截获传递给公共方法调用的参数的示例
Capture myTestCapture=new Capture()
someMockedObject.PublicMethod(Capture(myTestCapture))
结合使用

不幸的是,我既不能让这两种方法一起工作,也找不到将它们结合起来的例子。有人见过这样做的方法吗


FWIW,我怀疑Mockito可以做到这一点,但它并没有包含在我们的源代码/构建/测试系统中。如果可能的话,我希望避免在我们的系统中支持新库的过程。

任何类型的new
都只是一种静态方法。用同样的方法处理它。。。用一个方法把它包起来,去掉这个方法。在这种情况下,您希望在测试中返回一个mock,然后您可以测试与该对象的所有交互(并删除测试中对您正在创建的对象中的代码的依赖关系,该对象应该有自己的测试)

在你的测试中

public class MyTest {
  TestableProgram extends Program {
    @Override 
    ArbitraryType createArbitraryType() {
      return this.arbitraryTypeMock; 
    }
  }

  private ArbitraryType arbitraryTypeMock;
  private TestableMyClass objectToTest = new TestableProgram();

  // rest of your tests...

}
考虑到你的限制,我会这么做的


如果你能稍微改变一下你的限制,我会放松私有方法,我通常会放弃私有方法,而选择包默认,以使测试更容易。如果你的包中的人行为不端,通常是你的代码,所以隐私主要是保护你免受自己的伤害。(但我知道这不是你提出的问题的有效答案…。

如果你问如何获取localInstance的引用,那么下面的代码就足够了

@PrepareForTest(Program.class)
public class Test {
    @Test
    public void testMethod() {
        ArbitraryType passedLocalInstance = new ArbitraryType();
        PowerMock.expectNew(ArbitraryType.class).andReturn(passedLocalInstance );

        //remainder of the test method

        assertEquals(14.2, passedLocalInstance .getValue());
    }
}

由于java是按引用传递的,passedLocalInstance将是传递到方法调用中的参数。这回答了你的问题吗?

我喜欢这个主意,但不幸的是,这不是一个选择。“Program”类示例是产品代码,现在不是通过该类提取newingarbirytypes的好时机。
@PrepareForTest(Program.class)
public class Test {
    @Test
    public void testMethod() {
        ArbitraryType passedLocalInstance = new ArbitraryType();
        PowerMock.expectNew(ArbitraryType.class).andReturn(passedLocalInstance );

        //remainder of the test method

        assertEquals(14.2, passedLocalInstance .getValue());
    }
}