Question

Following are my classes

class Parent{
    private AddressService addressService = ServiceLocator.getService(AddressService.class);

    protected void doSomeJob(){
        addressService.doThat();
    }
}

class Child extends Parent{

    protected void doSomeJob(){
        super.doSomeJob();
    }

}

@RunWith(PowerMockRunner.class)
@PrepareForTest({ServiceLocator.class})
class ChildTest{

    @Test
    public void doSomeJob(){
        PowerMockito.mockStatic(ServiceLocator.class);
        AddressService addressService = Mockito.mock(AddressService.class);
        PowerMockito.when(ServiceLocator.getService(AddressService.class)).thenReturn(addressService);

        Child original = new Child();
        Child spiedObj = PowerMockito.spy(original);
        spiedObj.doSomeJob();
    }

}

Here ServiceLocator.getService() is a static method which look-up and returns the bean from application context. So, I mocked that static class and ask to return AddressService.class instance when it ask for ServiceLocator.getService(AddressService.class).

For my unit test when I spy()/mock() Child class that addressSerive instance have not assigned any value. But when I create a instance using new operator, I can see mock AddressService is assigned to the field. What am I missing here and how can I assigne value to that parent field when I do spy() on it's child instance?

Thanks

Was it helpful?

Solution

As I don't see any answers I tried following and it worked fine(which I tried to avoid doing)

@RunWith(PowerMockRunner.class)
@PrepareForTest({ServiceLocator.class})
class ChildTest{

    @Test
    public void doSomeJob(){
        PowerMockito.mockStatic(ServiceLocator.class);
        AddressService addressService = Mockito.mock(AddressService.class);
        // commented as no more required
        // PowerMockito.when(ServiceLocator.getService(AddressService.class)).thenReturn(addressService);

        Child original = new Child();
        Child spiedObj = PowerMockito.spy(original);
        // using Whitebox API
        Whitebox.setInternalState(spiedObj, AddressService.class, addressService);
        spiedObj.doSomeJob();
    }

}

Here I have used Whitebox API to set member variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top