nkxiaochuan / powermock

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

mockStatic doesn't work as expected with Mockito's @InjectMocks #519

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Using PowerMock 1.5.6, Mockito 1.9.5, JUnit 4.11.
When trying to mock an object Bar with static factory getInstance, and using it 
in object Foo, it will not work when instantiating it using @InjectMocks 
annotation.

See the following test:

Foo.java:
  package powermock;
  public class Foo {
    Bar bar = Bar.getInstance();
    public void doWork(){
      bar.doSomething();
      System.out.println("Did some work!");
    }
  }

Bar.java:
  package powermock;
  public class Bar {
    public static Bar getInstance(){
      return new Bar();
    }

    public void doSomething() {
      System.out.println("Did Something!");
    }
  }

FooBarTest:
  package powermock;

  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.InjectMocks;
  import org.mockito.Mockito;
  import org.powermock.api.mockito.PowerMockito;
  import org.powermock.core.classloader.annotations.PrepareForTest;
  import org.powermock.modules.junit4.PowerMockRunner;

  @RunWith(PowerMockRunner.class)
  @PrepareForTest({Bar.class,Foo.class})
  public class FooBarTest {
    @InjectMocks
    Foo injectedFoo;

    @Test
    public void constructorFooTest(){
        PowerMockito.mockStatic(Bar.class);
        Bar barMock = PowerMockito.mock(Bar.class);
        PowerMockito.when(Bar.getInstance()).thenReturn(barMock);
        Foo foo=new Foo();
        foo.doWork();
        Mockito.verify(barMock).doSomething();
        // Success
    }

    @Test
    public void injectedFooTest(){
        PowerMockito.mockStatic(Bar.class);
        Bar barMock = PowerMockito.mock(Bar.class);
        PowerMockito.when(Bar.getInstance()).thenReturn(barMock);
        injectedFoo.doWork();
        Mockito.verify(barMock).doSomething();
        // Fail
    }
  }

I expect both test to succeed. Needless to say, in case @Inject or @Autowired 
fields exists in Bar, they won't get injected in the succeeding test - so using 
the new operator is not a walk-around.

Original issue reported on code.google.com by yonatan.graber on 7 Oct 2014 at 6:17