如何使用mockito或powermockito在超类中设置私有变量的值

时间:2016-02-03 07:40:23

标签: unit-testing junit mocking mockito powermockito

我有三个类A,B和C其中A是抽象类,B也是抽象类,B扩展A和C是非抽象的,扩展了B.我有名称变量AddressService addressService在类中是公共的B并且是A类中的私有。我正在为C类编写一个非抽象的调试用例,并且在A类和A类中调用方法我需要设置AddressService addressService变量的值,该变量用于调用a方法。 AddressService是一个有方法的接口,我在我的超类A中调用其中一个方法。以下是我的代码

public interface AddressService{
void test();
}

public abstract class A{

    private AddressService addressService = (AddressService) ServiceLocatorBeanFactory.getService(AddressService.class);

 public void createDocument(){
 addressService . test();
}

}

public abstract class B extends A{
public AddressService addressService = (AddressService) ServiceLocatorBeanFactory.getService(AddressService.class);
}

public class C extends B {
}

这是我的测试类

@RunWith(PowerMockRunner.class)
@PrepareForTest({ServiceLocatorBeanFactory.class})
public class createTest {

    @SuppressWarnings("unchecked")
    @Test
    public void createTurnaroundDocument() throws Exception{

        PowerMockito.mockStatic(ServiceLocatorBeanFactory.class);       

        AddressService addressService = Mockito.mock(AddressService.class);
        PowerMockito.when(ServiceLocatorBeanFactory.getService(AddressService.class)).thenReturn(addressService);

        C original = new C();
        C handler = PowerMockito.spy(original);
        handler.createDocument();
    }
}

我尝试设置A类中存在的AddressService addressService的值,它以多种方式呈现,但仍然是null,我得到NullPointer异常。

以下是不同的方式

1.Whitebox.setInternalState(handler, AddressService.class, addressService);

当我以这种方式设置时,该值未设置且为null并且给出了NullPointerException

2.MemberModifier.field(A.class, "addressService").set(A.class, addressService);

当我这样设置时,我得到以下异常

java.lang.IllegalArgumentException:无法将AddressService字段A.addressService设置为java.lang.Class

3.Whitebox.setInternalState(A.class, AddressService.class, addressService);

当我这样设置时,我得到以下异常

org.powermock.reflect.exceptions.FieldNotFoundException:没有可从" AddressService"分配的静态字段。可以在A的类层次结构中找到。

4.Whitebox.setInternalState(A.class, "addressService", addressService);

当我这样设置时,我得到以下异常

org.powermock.reflect.exceptions.FieldNotFoundException:没有名为" addressService"的静态字段可以在A的类层次结构中找到。

有没有办法可以使用Mockito或PowerMockito设置超类中存在的私有变量的值。请帮忙

1 个答案:

答案 0 :(得分:0)

MemberModifier.field(A.class, "addressService").set(A.class, addressService);

这是错误的:java.lang.reflect.Field.set如果要设置非静态方法而不是类,则需要类的实例。可能仍然不起作用,也许你必须首先在场上使用setAccessible(true)

Field field = MemberModifier.field(A.class, "addressService");
field.setAccessible(true);
field.set(c, addressService);

你可以用纯粹的反射来做第一行......

Field field = A.class.getDeclaredField( "addressService" );
field.setAccessible(true);
field.set(c, addressService);

但当然,最大的谜团是:为什么你有两次相同的变量?闻起来像坏代码。让内在的一个受到保护而不是静态,一个好的东西不太可能来自两个。