user1192878
user1192878

Reputation: 734

How to run PowerMock on dynamically created TestCase

I was trying to mock my test suites. My test framework creates test cases by scanning test files on disk. So each time the test cases are dynamically created. I was trying to use PowerMock. Below is the thing I tried first.

public class GroupTestcase_T extends TestSuite {
     static void run() {
         scan();
         junit.textui.TestRunner.run(g);
     }
     static void scan() {
         // scan disk
         for (MyTestCase t : tests) { addTest(t); }
     }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassToStub.class)
public class MyTestCase extends TestCase {
     public MyTestCase(TestInfo info) {...}

     @Override
     protected void setUp() throws Exception {
         PowerMockito.mockStatic(ClassToStub.class);
         when(ClassToStub.methodToStub())
                .thenReturn(new FakeProxy());
     }
     @Test
     public void test() throws Exception {
         // Test!
     }
}

Above code seems not working:

Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. 2. inside when() you don't call method on mock but on some other object. 3. the parent of the mocked class is not public. It is a limitation of the mock engine.

I traced the code and found that PowerMockRunner are not called at all. Also I tried manually force Junit to run it with PowerMockRunner:

Result result = junit.run(new PowerMockRunner(MyTestCase.class));

PowerMockRunner has only one constructor that takes the test class as parameter. My test cases are different each time but all share the same class.

Any idea how to use PowerMock if TestCase are dynamically created? I was using Junit 4 / PowerMock 1.5

Upvotes: 1

Views: 2803

Answers (1)

gontard
gontard

Reputation: 29520

You can generate your tests with the parameterized tests feature and apply the @PowerMockRule.

import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;

@RunWith(Parameterized.class)
@PrepareForTest(ClassToStub.class)
public class MyTestCase{
    @Parameters
    public static Collection<Object[]> scan() {
        return Arrays.asList(new Object[][] {
        { new TestInfo() }, { new TestInfo() } });
    }

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    public MyTestCase(TestInfo info) {
        // ...
    }

    @Test
    public void test() throws Exception {
        PowerMockito.mockStatic(ClassToStub.class);
        PowerMockito.when(ClassToStub.methodToStub()).thenReturn(new FakeProxy());
        assertTrue(ClassToStub.methodToStub() instanceof FakeProxy);
    }
}

Beware, in your example, you are mixing junit 3 (extends TestSuite, protected setUp) and junit 4 (@Test) test definitions.

Upvotes: 0

Related Questions