使用PowerMock模拟私有方法时已被模拟但仍为null

问题描述 投票:0回答:1

这是我的项目的简要代码, Foo 类:

public class Foo {
    @Autowired
    protected Mapper mapper;

    protected User getUser() {
        // ...
        return user;
    }
}

扩展 Foo 的 Bar 类:

public class Bar extends Foo{

    public void func(String param1, String param2) {
        Result result = this.validateParams(param1, param2);
        // ...
        Entity entity = super.mapper.mapTo(param1, Entity.class);
        entity.setUserInfo(super.getUser().getInfo()); // null pointer exception
    }



    private Result validateParams(String param1, String param2) {
        // ...
        return Result.success();
    }
}

和测试班:

@RunWith(PowerMockRunner.class)
@PowerMockIgnore( {"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest({Bar.class}) // to mock private method
public class BarTest {
    @InjectMocks
    Bar bar;

    @Mock
    Mapper mapper;

    @Test
    public void testFunc() {
        bar = PowerMockito.spy(bar);
        bar.mapper = mapper; // or bar.mapper is null

        PowerMockito.doReturn(Result.success()).when(bar, validateParams, any(), any()); // mock private method

        User user = new User(); // mock user
        PowerMockito.doReturn(user).when(bar).getUser(); // doesn't work

        bar.func("param1", "param2");
    }
}

比较奇怪的是,我测试bar.func时,遇到

entity.setUserInfo(super.getUser().getInfo())
时,
super.getUser()
返回null,导致NPE。但我已经模拟了 getUser() 函数,这似乎不起作用。 期待您的建议和帮助,非常感谢。

我试图避免使用间谍(栏),假设它会导致实例的空副本(全部为空)。 我也尝试使用

Method methodGetUser = PowerMockito.method(Bar.class, "getUser");
    PowerMockito.replace(methodGetUser).with(new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return user;
        }
    });

但效果不佳(NPE)。

java mocking mockito powermock powermockito
1个回答
0
投票

@InjectMocks Bar bar;
已经创建了一个实例。
bar = PowerMockito.spy(bar);
分配一个新实例。原始
bar
实例对包装间谍一无所知。因此,您在间谍上定义的任何行为(使用
PowerMockito.doReturn(user).when(bar).getUser();
)在原始实例中都是不可见或不可访问的。

您必须保留原始参考资料:

public class BarTest {
    @InjectMocks
    Bar bar;
    Bar barSpy;

    @Mock
    Mapper mapper;

    @Test
    public void testFunc() {
        barSpy = PowerMockito.spy(bar);
        // bar.mapper = mapper; // this should not be required, `@InjectMocks` must take care of this

        PowerMockito.doReturn(Result.success()).when(bar, validateParams, any(), any()); // mock private method

        User user = new User();
        PowerMockito.doReturn(user).when(bar).getUser(); // stub original instance

        bar.func("param1", "param2");
    }
}

但是你为什么要监视呢?您没有验证您的间谍的任何通话吗?

相关:为什么在执行单元测试时没有调用我的模拟方法?

© www.soinside.com 2019 - 2024. All rights reserved.