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

我的类中有一个私有字段和一个方法,如果设置了某个标志并且地图包含某个值,则该方法正在修改它。我想测试该方法并查看结果。这是代码(为简洁起见,省略了不相关的字段和方法):


我的课:


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 并模拟它们,但是整个测试就失去了意义。


宝慕林4294392
浏览 143回答 3
3回答

倚天杖

在您的情况下,您可以使用Spy而不是模拟。这将触发构造函数并将一个空列表分配给私有变量,从而逃避 NPE:private UsersLoader loader;@Beforepublic void setUp() {&nbsp; loader = spy(new UsersLoader());}现在您不需要进行此调用:&nbsp; doCallRealMethod().when(loader).loadExternalUsers(anyBoolean());请记住,您需要模拟任何不需要在实现时触发的方法。

眼眸繁星

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

慕的地8271018

首先,将初始化移动到字段的声明中:private Collection<User> users = new ArrayList<>();然后,你可以用你自己的 mock 注入这个字段:@RunWith(MockitoJUnitRunner.class)class UsersLoaderTest {&nbsp; &nbsp; &nbsp; &nbsp;@Mock&nbsp; &nbsp; &nbsp; &nbsp;private Collection<User> users;&nbsp; &nbsp; &nbsp; &nbsp;@InjectMocks&nbsp; &nbsp; &nbsp; &nbsp;private UsersLoader loader;}然后验证是否users.add()已与您预期的用户一起调用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java