mockito 使用PowerMock模拟私有方法时已模拟但仍为空

7ajki6be  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(128)

下面是我的项目类Foo的简短代码:

public class Foo {
    @Autowired
    protected Mapper mapper;

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

类Bar扩展Foo:

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()函数,它似乎不起作用。期待您的建议和帮助,非常感谢。
我试图避免使用spy(bar),假设它会导致示例的空副本(全部为null)。我还试着用

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

dbf7pr2w

dbf7pr2w1#

@InjectMocks Bar bar;已创建示例。bar = PowerMockito.spy(bar);分配一个新示例。原始bar示例不知道 Package 间谍的任何信息。因此,您在spy(使用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");
    }
}

但你为什么要监视我?你不核实你的间谍的通话记录吗?
标签:Why are my mocked methods not called when executing a unit test?

相关问题