【问题标题】:How to set the value of private variable in a super class using mockito or powermockito如何使用 mockito 或 powermockito 在超类中设置私有变量的值
【发布时间】:2016-02-03 07:40:22
【问题描述】:

我有三个类A,B和C,其中A是抽象类,B也是抽象类,B扩展A,C是扩展B的非抽象类。我有一个名为AddressService addressService的变量,它在类中是公共的B 并且在 A 类中是私有的。我正在为非抽象类 C 编写一个测试用例,并调用 A 类和 A 类中的方法,我需要设置用于调用的 AddressService addressService 变量的值方法。 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:在 A 的类层次结构中找不到可从“AddressService”分配的静态字段。

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

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

org.powermock.reflect.exceptions.FieldNotFoundException: 在 A 的类层次结构中找不到名为“addressService”的静态字段。

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

【问题讨论】:

    标签: unit-testing junit mocking mockito powermockito


    【解决方案1】:
    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);
    

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

    【讨论】:

    • 根据您的代码 field.set(a, addressService);这个“a”是什么,这个值是从哪里来的
    • “a”持有什么值。它是 A 类的实例吗?正如我已经提到的,我的 A 类也是抽象的
    • 对不起,应该是“c”,因为你的对象 c 是我们需要的 A 对象。
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2017-10-13
    • 2014-09-21
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2013-09-14
    相关资源
    最近更新 更多