mtj
mtj

Reputation: 3554

Powermock without JUnit

to extract some data from a legacy application, I currently use powermock to prepare a few quite-mangled-up classes and replace a few dependencies with mocks.

Thus, I have a JUnit test, which essentially does:

@RunWith(PowerMockRunner.class)
@PrepareForTest(LegacyDependency.class)
public class ThisIsNotReallyATest {
    @Test
    public void extractData() {
        ... prepare and wire mocks

        // new ClassUnderTest() will essentally call LegacyDependency.getInstance()
        Object result = new ClassUnderTest().doSomething();
        // save result for later reference
    }
}

Thus: this is NOT A TEST. This is a utility class which uses Powermock features to get around various badly modeled dependencies.

As using a test framework to create a utility which is not connected to unit testing whatsoever makes me feel real bad, the question is:

Can I use powermock (esp. the the PrepareForTest feature for static/final/etc.) in a standalone piece of software? If so: how?

Upvotes: 0

Views: 440

Answers (2)

I agree with @rkosegi's comment - you are misusing PowerMock for purpose for which it is not intended.

However, I understand your need to utilize PowerMock's cool reflection features. They are unfortunately very tightly coupled with testing framework features which you don't need. Since PowerMock runner initializes test environment in different classloader and tweaks some classes before putting them into this environment, you can mimic the PowerMock's work to do exactly the same, without need for test class, annotation etc.

In my blog (in Czech), I shown how to use Powermock's internals to get method name for given method reference. It was not as comfortable as Powermockito (actually it was very painful) but in retrospect you need just 1. reuse class loader, 2. implement class loader work (tweaking your ClassUnderTest in Javassist), 3. profit :-)

Anyway I warn you about production usage of such code, it's rather playing around.

Upvotes: 0

user180100
user180100

Reputation:

IMHO, the question is an X/Y problem, but

Let's say the constructor for ClassUnderTest is:

ClassUnderTest() {
    this.legacyDep = LegacyDependency.getInstance();
    // ...
}

And that you don't want some LegacyDependency behavior, you could do some refactoring like that:

// you can provide your own "LegacyDependency" that does nothing or something
ClassUnderTest(LegacyDependency legacyDep) {
    this.legacyDep = legacyDep;
    // ...
}

// old way
ClassUnderTest() {
    this(LegacyDependency.getInstance());
    // ...
}

Upvotes: 1

Related Questions