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



我有三个类A,B和C,其中A是抽象类,B也是抽象类,B扩展A,C是扩展B的非抽象类。我有名称为地址服务的变量,它在 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 Exception。

以下是不同的方式

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

当我以这种方式设置时,值未设置并且为空,并给我空指针异常

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 设置超类中存在的私有变量的值。请帮忙

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);

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

相关内容

  • 没有找到相关文章

最新更新