java - 在模拟类中初始化私有字段
问题描述
我的类中有一个私有字段和一个方法,如果设置了某个标志并且地图包含某个值,则该方法正在修改它。我想测试该方法并查看结果。这是代码(为简洁起见,省略了不相关的字段和方法):
我的课:
class UsersLoader {
private Collection<User> users;
private Map<Integer,Boolean> status;
UsersLoader() {
users = new ArrayList<>();
status = new HashMap<>();
}
protected loadExternalUsers(boolean condition) {
Collection<User> externalUsers = LoadUsersFromSomeExternalSource();
if (condition && status.get(SOME_KEY)) {
users.addAll(externalUsers);
} else {
/* do not modify my users */
}
}
}
我的测试:
import static org.mockito.Mockito.mock;
public class UsersLoaderTest {
private UsersLoader loader;
@Before
public void setUp() {
loader = mock(UsersLoader.class);
doCallRealMethod().when(loader).loadExternalUsers(anyBoolean());
}
@Test
public void testLoadingWhenFlagIsTrue {
Collection<User> users = loader.loadExternalUsers(true);
assertThat(users.size() == 1);
}
@Test
public void testLoadingWhenFlagIsFalse {
Collection<User> users = loader.loadExternalUsers(false);
assertThat(users.size() == 0);
}
}
当我运行测试时,我得到了一个NullPointerException
in UsersLoader
class,与检查status.get(SOME_KEY)
. 即使我解决了这个问题,下一个 NPE 也将是下面的一行,因为 myusers
将为空。如何在我的模拟类中初始化私有字段以便我可以使用它们?我可以创建一个 getter 和一个 setter 并模拟它们,但是整个测试就失去了意义。
解决方案
在您的情况下,您可以使用Spy而不是模拟。
这将触发构造函数并将一个空列表分配给私有变量,从而逃避 NPE:
private UsersLoader loader;
@Before
public void setUp() {
loader = spy(new UsersLoader());
}
现在您不需要进行此调用:
doCallRealMethod().when(loader).loadExternalUsers(anyBoolean());
请记住,您需要模拟任何不需要在实现时触发的方法。
推荐阅读
- c - C 使用 dup2 管道子级和父级
- ruby-on-rails - Rails jsonb - 当 jsonb 保存到 Postgresql 数据库时,防止 JSON 键重新排序
- spring - Spring Data Solr - 多核支持
- c - 如何制作 argv[1] 的副本
- django - Django:在 get_context_data 中设置初始值无法按预期工作
- listview - 如何找到下一个未选中的 ListView 项?
- node.js - JWT Passport 不从中间件返回用户数据
- bash - 如何用自定义别名替换内部 git 命令,例如 `git status`
- ios - 启动图像和打开动画是否会导致我的应用冻结?
- javascript - 在 React 中更改所需的输入消息