如何在Java中的被测类中注入被声明为private static的对象的模拟?

时间:2018-09-07 06:51:21

标签: java junit mockito

我有一个ManageUser类,如下所示:

public class ManageUser {
private static UserBO gUserBO = new UserBO();

 public String method1() {

    gUserBO.callSomeFunction();

    gUserBO.callSomeOtherFunction();

  }
}

现在,我有一个测试类,我想在其中测试method1(),并且由于方法callSomeFunction()和callSomeOtherFunction()最终进行数据库调用,因此我想模拟对这些方法的调用。由于ManageUser中的对象是静态的,因此无法通过模拟来做到这一点。我该如何进行?我是Junit和Mockito的新手,似乎找不到相关的答案。

2 个答案:

答案 0 :(得分:0)

尝试使用Power Mockito:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ManageUser.class})
public class ClassInTest {

    @Test
    public void testStatic() {
       ManageUser mUser = new ManageUser();
       Field field = PowerMockito.field(ManageUser.class, "gUserBO");
       field.set(ManageUser.class, mock(UserBO.class));
       ...
    }
}

答案 1 :(得分:0)

您“无法通过使用模拟做到这一点”,因为您的课程设计不良。解决方法是,您可以使用PowerMock(如@ S.K。建议)来模拟静态字段,但这只会抑制类的实际问题。

更好地把握机会并改进代码,以提高可测试性和可开发性:

步骤1:为您的类UserBO创建一个接口,并使其实现。

public interface UserService {
    void callSomeFunction();
    void callSomeOtherFunction();
}

public class UserBO implements UserService { ... }

第2步:更改类ManageUser,以通过构造函数获取UserService的任何实现。

public class ManageUser {
    private final UserService userService;

    public ManageUser(UserService userService) {
        this.userService = userService;
    }

    public String method1() {
        userService.callSomeFunction();
        userService.callSomeOtherFunction();
    }
}

第3步:更改类ManageUser的调用方以提供一个UserService

所以不是

ManageUser manager = new ManageUser();

使用

ManageUser manager = new ManageUser(new UserBO());

步骤4:现在,您可以轻松地在测试中模拟UserService并使用该模拟构造一个ManageUser


该设计还使DI框架(例如Spring)能够注入(或 autowire )组件。