[英]How to inject the mock of an object which is declared as private static in the class under test in java?
I have a class ManageUser as below: 我有一个类ManageUser,如下所示:
public class ManageUser {
private static UserBO gUserBO = new UserBO();
public String method1() {
gUserBO.callSomeFunction();
gUserBO.callSomeOtherFunction();
}
}
Now, I have a test class where I want to test method1() and since the methods callSomeFunction() and callSomeOtherFunction() end up making database calls I want to mock the calls to those methods. 现在,我有一个测试类,我要在其中测试method1(),并且由于方法callSomeFunction()和callSomeOtherFunction()最终进行数据库调用,因此我想模拟对这些方法的调用。 I am unable to do that by using mock since the object in ManageUser is static.
由于ManageUser中的对象是静态的,因此无法通过模拟来做到这一点。 How do I proceed?
我该如何进行? I am new to Junit and Mockito and can't seem to find relevant answers.
我是Junit和Mockito的新手,似乎找不到相关的答案。
Try using Power Mockito: 尝试使用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));
...
}
}
You are "unable to do that by using mock" because your class is badly designed. 您“无法通过使用模拟做到这一点”,因为您的类设计不良。 As a workaround, you could use PowerMock (as @SK suggested) to mock the static field but that will only suppress the real problem of your class.
作为一种解决方法,您可以使用PowerMock (如@SK所建议的)模拟静态字段,但这只会抑制类的实际问题。
Better take the chance and improve the code for better testability and evolvability: 更好地把握机会并改进代码以提高可测试性和可扩展性:
Step 1: Create an interface for your class UserBO
and let it implement it. 步骤1:为您的类
UserBO
创建一个接口,并使其实现。
public interface UserService {
void callSomeFunction();
void callSomeOtherFunction();
}
public class UserBO implements UserService { ... }
Step 2: Change your class ManageUser
to get any implementation of UserService
through a constructor. 步骤2:更改您的类
ManageUser
以通过构造函数获取UserService
任何实现。
public class ManageUser {
private final UserService userService;
public ManageUser(UserService userService) {
this.userService = userService;
}
public String method1() {
userService.callSomeFunction();
userService.callSomeOtherFunction();
}
}
Step 3: Change the calling side of your class ManageUser
to provide a UserService
. 步骤3:更改类
ManageUser
的调用方以提供UserService
。
So instead of 所以代替
ManageUser manager = new ManageUser();
use 采用
ManageUser manager = new ManageUser(new UserBO());
Step 4: Now you can easily mock a UserService
in your test and construct a ManageUser
with the mock. 步骤4:现在,您可以轻松地在测试中模拟
UserService
并使用该模拟构造ManageUser
。
This design also enables DI frameworks (eg Spring) to inject (or autowire ) the components. 这种设计还使DI框架(例如Spring)能够注入 (或自动装配 )组件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.