Инициализировать приватное поле в проверяемом классе - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть личное поле в моем классе и метод, который модифицирует его, если установлен определенный флаг, И если карта содержит определенное значение.Я хочу проверить этот метод и увидеть результат.Вот код (нерелевантные поля и методы для краткости опущены):

Мой класс:

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 в UsersLoader классе, в строке с предложением IF, который проверяет status.get(SOME_KEY).Даже если я решу это, следующий NPE будет на одну строку ниже, потому что мой users будет нулевым.Как я могу инициализировать приватные поля в моём классе, чтобы я мог работать с ними?Я могу создать геттер и сеттер, а также высмеивать их, но тогда весь тест теряет смысл.

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Сначала переместите инициализацию к объявлению поля:

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

Затем вы можете ввести это поле с помощью собственного макета:

@RunWith(MockitoJUnitRunner.class)
class UsersLoaderTest {
       @Mock
       private Collection<User> users;
       @InjectMocks
       private UsersLoader loader;
}

, а затем убедиться, чтоusers.add() вызвано с ожидаемыми пользователями.

0 голосов
/ 12 февраля 2019

Не издевайтесь над UsersLoader.class, это класс, содержащий методы, которые вы собираетесь тестировать.Когда вы создаете макет, макетный класс не будет реализован, вместо этого вы можете смоделировать функциональные возможности класса.Скорее следите за этим или просто создайте экземпляр и предоставьте проверку рукописной проверки на функциональность.В последнем случае вам не нужен Mockito.Таким образом, вы можете следить за этим и использовать функцию mockito для проверки работоспособности

0 голосов
/ 12 февраля 2019

В вашем случае вы могли бы использовать Spy вместо макета.

Это вызвало бы конструктор и присвоило бы пустой список закрытой переменной, таким образом избегая NPE:

private UsersLoader loader;

@Before
public void setUp() {
  loader = spy(new UsersLoader());
}

Теперь вам не нужно совершать этот вызов:

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

Просто имейте в виду, что вам нужно смоделировать любые методы, которые не нужно запускать как реализованные.

...