为了账号安全,请及时绑定邮箱和手机立即绑定

在模拟类中初始化私有字段

在模拟类中初始化私有字段

宝慕林4294392 2022-06-15 17:37:39
我的类中有一个私有字段和一个方法,如果设置了某个标志并且地图包含某个值,则该方法正在修改它。我想测试该方法并查看结果。这是代码(为简洁起见,省略了不相关的字段和方法):我的课: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);   }}当我运行测试时,我得到了一个NullPointerExceptionin UsersLoaderclass,与检查status.get(SOME_KEY). 即使我解决了这个问题,下一个 NPE 也将是下面的一行,因为 myusers将为空。如何在我的模拟类中初始化私有字段以便我可以使用它们?我可以创建一个 getter 和一个 setter 并模拟它们,但是整个测试就失去了意义。
查看完整描述

3 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

在您的情况下,您可以使用Spy而不是模拟。


这将触发构造函数并将一个空列表分配给私有变量,从而逃避 NPE:


private UsersLoader loader;


@Before

public void setUp() {

  loader = spy(new UsersLoader());

}

现在您不需要进行此调用:


  doCallRealMethod().when(loader).loadExternalUsers(anyBoolean());

请记住,您需要模拟任何不需要在实现时触发的方法。


查看完整回答
反对 回复 2022-06-15
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

不要模拟 UsersLoader.class,这是包含您要测试的方法的类。当您创建一个模拟时,模拟类将不会被实现,而是您可以模拟该类的功能。而是监视它或只是实例化并为功能提供检查手写检查。在后一种情况下,您根本不需要 Mockito。所以你可以窥探它并使用mockito的特性来测试它的功能



查看完整回答
反对 回复 2022-06-15
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

首先,将初始化移动到字段的声明中:


private Collection<User> users = new ArrayList<>();

然后,你可以用你自己的 mock 注入这个字段:


@RunWith(MockitoJUnitRunner.class)

class UsersLoaderTest {

       @Mock

       private Collection<User> users;

       @InjectMocks

       private UsersLoader loader;

}

然后验证是否users.add()已与您预期的用户一起调用。


查看完整回答
反对 回复 2022-06-15
  • 3 回答
  • 0 关注
  • 142 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号