tiebin-zhang / powermock

Automatically exported from code.google.com/p/powermock
Apache License 2.0
0 stars 0 forks source link

PowerMockRule interacts poorly with mocked member variables #362

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

Following the methodology here: 
http://code.google.com/p/powermock/wiki/PowerMockRule

Set up a test that mocks some sort of static class.  In this case it's a custom 
SQLUtils object that takes a java.sql.Connection and a string.  For our 
purposes here I am using xstream, but I have been able to reproduce it with 
objenesis.  Here's a standard pattern for testing:
@PrepareForTest({SQLUtils.class})
public class PowerMockTest {

    @Rule
    public final PowerMockRule powermock = new PowerMockRule();

    private final Connection conn = mock(Connection.class);

    @Before
    public void setUp() throws Exception {
        reset(conn);
        PowerMockito.mockStatic(SQLUtils.class);
    }

    @Test
    public void testCall() throws Exception {

        SQLUtils.execute(conn, "my sql");
    }
}

What is the expected output? What do you see instead?

I'd expect it to run.  Instead it throws the attached exception.

What version of the product are you using?

1.4.11 with Mockito 1.9 and junit 4.10.  Running in Eclipse, dependencies being 
managed by Maven. 

Please provide any additional information below.

The following code executes without issue:

@PrepareForTest({SQLUtils.class})
public class PowerMockTest {

    @Rule
    public final PowerMockRule powermock = new PowerMockRule();

    private Connection conn;

    @Before
    public void setUp() throws Exception {
        conn = mock(Connection.class);
        PowerMockito.mockStatic(SQLUtils.class);
    }

    @Test
    public void testCall() throws Exception {
        SQLUtils.execute(conn, "my sql");
    }
}

It also executes without any issue if I use the @RunWith(PowerMockRunner.class) 
annotation instead of the PowerMockRule.

The following things were tried to get the Rule to work:

1) I could not find any combination of things I could put into @PowerMockIgnore 
that would fix the issue (attempting ignoring java.sql.* java.sql.Connection 
org.mockito.* etc). Bizarrely, ignoring SQLUtils worked, but then the class 
wasn't mocked. 
2) Initializing the objects via a constructor.
3) Marking the rule as Static. 
4) Changing the dependency ordering (if this is the problem, I couldn't find 
the exact combination).
5) Putting the Rule declaration in a parent class (along with putting the 
declarations in a parent class). 

So far the only solution I've found is to initialize all of my mocks in the 
setUp() method.  I can do this as a workaround, but  I couldn't find any 
documentation indicating that what I am doing is not supported.

Original issue reported on code.google.com by nachtr...@gmail.com on 18 Jan 2012 at 10:15

Attachments:

GoogleCodeExporter commented 9 years ago
Hmmm... It seems like it fails to deep clone the mock because it's not loaded 
by the same classloader.

Feel free to try the javaagent based Rule instead.

Original comment by johan.ha...@gmail.com on 20 Jan 2012 at 4:10