Question

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

Was it helpful?

Solution

So what I think you need is a similar functionality to C#'s Reflection.Emit:

While I haven't done this myself, I think you should be able to use reflection/emission and dynamic type creation in order to achieve what you're looking for. However, I would still like to mention that if you're trying to test "functionality" that's not int he code path of the function you're testing, then you probably shouldn't be testing it at all. For example:

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

In this case get has no code path that would return null, so you shouldn't need to test for null. I'm not sure if I understood your question 100% correctly, especially why you're testing for null, but consider the above advice and see what works for you.

OTHER TIPS

are you looking for something like javassist? You can instrument code and inject your methods at runtime. I personally try to avoid byte code manipulation as much as possible. Can you not have these overrides in your code base rather than doing on the fly? May be something like wrappers?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top