2

对于公共方法调用,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消耗的对象privateHelperToIntercept()

我找到了很多模拟私有方法调用的例子;PowerMock 的expectPrivate(partiallyMockedObject, "nameOfPrivateMethod", arg1, arg2)效果很好。我还找到了拦截​​传递给公共方法调用的参数的示例;Capture<Type> myTestCapture = new Capture<Type>()结合someMockedObject.PublicMethod(capture(myTestCapture)).

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

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

4

2 回答 2

1

如果您询问如何获取对 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 将是传递给方法调用的参数。这回答了你的问题吗?

于 2013-04-10T21:08:29.440 回答
0

new任何类型的只是一个静态方法。以同样的方式处理它......将它包装在一个方法中,存根该方法。在这种情况下,您想在测试中返回一个模拟,然后您可以测试与该对象的所有交互(并在您的测试中删除对您正在创建的对象中的代码的依赖,该对象应该有自己的测试)

public Program {

    // your above code up to object creation
    ArbitraryType localInstance = createArbitraryType();
    // rest of your above code here


  ArbitraryType createArbitraryType() {
    return new ArbitraryType();
  }
}

在你的测试中...

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

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

  // rest of your tests...

}

鉴于您的限制,我就是这样做的。

如果可以稍微改变您的约束,我会放松私有方法,我通常会取消私有方法,转而使用包默认值以使测试更容易。如果您包中的人行为不端,通常是您的代码如此私密,无论如何主要是保护您免受自己的伤害。(但我知道这不是您提出的问题的有效答案......)。

于 2012-08-15T20:52:36.090 回答