# Limitation of PowerMockito.whenNew()

Powemock is a very powerful tool in any Java Developer's arsenal, it allows a developer to change his code at the bytecode level. This is especially beneficial when we want to modify some functionality of source (System Under Test).

#### Whey we need `whenNew()` ? <a href="#heading-whey-we-need-whennew" id="heading-whey-we-need-whennew"></a>

`whenNew()` allows us to inject our `fake` or `mock` instead of actually creating a new object of said class.

This works great, we just need to add our class in `@PrepareForTest` annotation and PowerMock will inject our mock. Just like that.

Here is an example class:

```java
// Example Source Class
public class ExampleClass {
    public int getHeight() {
        // Lets say we have a generic method which provides different result base on the provided id
        final CustomClass customClassInstance = new CustomClass();
        return customClass.getHeight();
    }
}
```

and here is a test case using `whenNew()` injection.

```java
@RunWith(PowerMockRunner.class)
@PrepareForTest({
    ExampleClass.class
})
public class ExampleClassTest {

    private ExampleClass classUnderTest;

    @Before
    public void setUp() throws Exception {
        // Create constructor of ExampleClass
        classUnderTest = new ExampleClass();
    }

    @Test
    public void getHeight_shoudReturnHeightOfView() throws NoSuchMethodException {
        final int expectedHeight = 100;
        // Given
        final CustomClass mckCustomClass = Mockito.mock(CustomClass.class);
        Mockito.when(mckCustomClass.getHeight()).theReturn(expectedHeight);
        // Make sure you match exact parameters while mocking (same as we do for Mockito.mock statements).
        // There is also withArguments(first, second, ....)
        // and withAnyArguments() for cases when you don't care for arguments passed.
        PowerMockito.whenNew(CustomClass.class).withNoArguments().thenReturn(mckCustomClass);

        final int actualResult = classUnderTest.getHeight();

        Assert.assertEquals(expectedHeight, actualResult);
    }
}
```

#### Now let's come to the problem... <a href="#heading-now-lets-come-to-the-problem" id="heading-now-lets-come-to-the-problem"></a>

Let's say you have the following class to test:

```java
// ClassToTest
public class ClassToTest {
    // heavy method
    private void doInBackground() {
        new Thread() {
            @Override
            public void run() {
                final CustomClass customClassInstance = new CustomClass();
                int height = customClass.getHeight();
                // ... some heavey operation on height
            }
        }.start();
    }
}
```

Now, in the above example, a new instance of `CustomClass` is created inside a nested scope (`Thread`), hence modifying bytecode of `ClassToTest` will no longer work as `new CustomClass()` is not inside its scope.

#### What to do? <a href="#heading-what-to-do" id="heading-what-to-do"></a>

Powermock has other tools to deal with such situations, firstly, you need to add `CustomClass` in `@PrepareForTest()` and `suppress()` constructors and `stub()` `getHeight()` method to modify its behaviour according to your test requirements.

Here is example code:

```java
@RunWith(PowerMockRunner.class)
@PrepareForTest({
    ExampleClass.class,
    CustomClass.class
})
public class ExampleClassTest {

    private ExampleClass classUnderTest;

    @Before
    public void setUp() throws Exception {
        // Create constructor of ExampleClass
        classUnderTest = new ExampleClass();
    }

    @Test
    public void getHeight_shoudReturnHeightOfView() throws NoSuchMethodException {
        final int expectedHeight = 100;
        // Given
        PowerMockito.suppress(CustomClass.class.getConstructors());
        PowerMockito.stub(CustomClass.class.getMethod("getHeight")).toReturn(expectedHeight);
        // ...
    }
}
```

**Note:** PowerMock has `suppress()` , `sub()` and `replace()` methods to modify individual elements of any class. Please read more about methods declared in `PowerMockito` class and see if you find an alternate solution for your use case.
