0

I have a class that's composed of other objects/dependencies as follows:

public class One{
  
    private RedisPool redisPool;

    private static final WeakHashMap<String, Dedup<String>> CACHE = new WeakHashMap<>();

    private static final ObjectMapper mapper = new ObjectMapper();

    private BigQueryManager bigQueryManager;

    private RedisClientManager redisClientManager;

    private PubSubIntegration pubSub;

    public One(RedisPool redisPool, Configuration config) {

        this.redisPool = redisPool;

        bigQueryManager = new BigQueryManager(config);

        redisClientManager = new RedisClientManager(redisPool, config);

        pubSub = new PubSubIntegration(config);

    }

....
...
other methods    

}

I tried:

public class OneTest{
    
   @Mock
   RedisPool redisPool;

   @Mock
   Configuration config;

   @Before
   public void setUp(){
       MockitoAnnotations.initMocks(this);
       One one = new One(redisPool, config);
   }
}

But I'm not sure whether the objects constructed inside the constructor also get mocked, as I have used those objects in other methods inside the class.

How can I mock the objects constructed inside the constructor?

bigbounty
  • 16,526
  • 5
  • 37
  • 65
  • Short answer, you can't do that with `Mockito`, longer answer, you *can* mock constructors using PowerMockito, but that changes the bytecode of the classes, (including the one under test). An alternative would be to introduce a second constructor which accepts 4 arguments. Which you can then use in the test – Lino Aug 31 '20 at 10:10
  • I'm using `Powermockito`. So, how do I proceed? – bigbounty Aug 31 '20 at 10:12
  • The duplicates should point you into the right direction, also [this](https://www.baeldung.com/intro-to-powermock#mocking) tutorial from baeldung might help you additionally. What you want is to not mock the `One` constructor, but the 3 it invokes. Namely `BigQueryManager`, `RedisClientManager` and `PubSubIntegration` – Lino Aug 31 '20 at 10:15

1 Answers1

1

I don't think you can achieve this using Mockito alone, but you can if you also use PowerMockito.

This article gives an example that is quite similar to what you want to achieve.

Note that PowerMockitio will mess up any test coverage statistics that you are collecting.

EDIT

If the article disappears, the gist of it is that you need to annotate your Test class slightly differently

@RunWith(PowerMockRunner.class)
@PrepareForTest(One.class)
public class OneTest {

The @PrepareForTest annotation refers to the Class that you need to alter the bahaviour of - in your case the One class.

You then tell PowerMoncito to return an object you can control when a new instance is created. In your case

PowerMockito.whenNew(BigQueryManager.class)
            .withAnyArguments().thenReturn(mockBigQueryManager);
DaveH
  • 7,187
  • 5
  • 32
  • 53