0

What I wanna do is a method that can

  • generate instance of Class X (a class variable passed in arg) and
  • override some of it's method

More specifically, the parent class X I want to override contains

  • Contains no default constructor (e.g. all constructors with args)
  • Constructors calling non-private method within the same class

Originally I thought it's quite simple to use reflection or something similar, Then I found there's limitation on implementing my requirement.

I think this is achievable, since Mockito can do all kinds of method injection runtime.
Please anyone give some advise, Thanks.
The pseudo-code I image is like this:

createAndOverride(Class X) {
    X newObj = X.newInstance(args) {
        @override
        methodOfX(args2) {
            ...
        }
    }
    return newObj;
}
  • Original problem scenario

I was intended to test a Class which has several methods calling X1.get(), X2.get(), X3.get()
In some test case, I need to make Xn.get() to return something I can control for test (e.g. null)
Due to below constraint:

  • But due to mock tool restriction to JMock 1.0 (I have no control :( ), so I cannot just simply mock Xn.get() to returns "someSpecifiedObjects"
  • Xn has no null constructors and constructors calling non-private member

My workaround is self made Xn Class and pass them to test case to let Cn.get() to be expected
code example:

ClassToTest.SomeMethod(new X1() {
    @override
    get() {
        return someSpecifiedObjects;
    }
});

And this kind of thing is spread-ed over the Test Case.
Therefore, In order to reduce duplicate code, I would like to build a method to generate Xn instance with specified overrided method for test. e.g.

X1 x1 = createAndOverride(X1);

Then, the problem of this post comes

4

2 回答 2

1

你在寻找类似javassist的东西吗?您可以在运行时检测代码并注入您的方法。我个人尽量避免字节码操作。你能不能在你的代码库中没有这些覆盖,而不是即时执行?可能是包装纸之类的东西?

于 2011-10-29T03:25:49.660 回答
0

所以我认为你需要的是与 C# 类似的功能Reflection.Emit

虽然我自己没有这样做,但我认为您应该能够使用反射/发射和动态类型创建来实现您正在寻找的东西。但是,我仍然想提一下,如果您尝试测试不在您正在测试的函数的代码路径中的“功能”,那么您可能根本不应该测试它。例如:

SomeObjectInterface get()
{
    if(_someObjectStateIsSet)
    {
        // Return a concrete implementation A
        return new ConcreteImplA();
    }
    else
    {
        // Return a concrete implementation B
        return new ConcreteImplB();
    }
}

在这种情况下, get 没有会返回的代码路径null,因此您不需要测试null. 我不确定我是否 100% 正确理解了您的问题,尤其是您为什么要测试null,但请考虑上述建议,看看什么对您有用。

于 2011-10-30T15:52:57.550 回答