проблема if ... else в тесте mockito в Spring Boot - PullRequest
0 голосов
/ 15 января 2019

как написать контрольный пример mockito для оператора if ... else, который также включает в себя проверку исключений, я довольно смущен этим. UserService - это интерфейс

UserFactory.java

public class UserFactory {
    @Autowired
    private List<UserService> UserList;

    private final Map<String, UserService> UserMap = new HashMap<>();

    @PostConstruct
    public void initUserMap() {
        for (final UserService user : UserList) {
            UserMap.put(user.getUserId(), user);
        }
    }

    public UserService getUser(String userId) {
        final UserService userService = UserMap.get(userlId);
        if (null == userService) {
            throw new IllegalArgumentException("user are not in the group");
        }
        return userService;
    }
}

UserService (интерфейс)

public interface UserService{
  String getUserName();
  String getUserId();
}

вот мой тест, но он не правильный ...

@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {

    @Mock
    private UserService userService;

    @InjectMocks
    private UserFactory UserFactory;

    private Map<String, User> UserMap;

    private String userId = "123";

    @Before
    public void set_up(){
        UserMap = new HashMap<>();
        UserMap.put(userId, userService);
    }

    @Test
    public void getUser(){
        when(UserMap.get(userId)).thenReturn(userService);
        userService actual = userServiceFactory.getUser(userId);
        assertEquals(UserMap.get(userId), actual);
    }
}

1 Ответ

0 голосов
/ 15 января 2019

1) Вы пишете модульный тест, а не нарезанный тест или интеграционный тест. Поэтому здесь Spring Boot не имеет значения, поскольку вам не нужно загружать контейнер для проверки логики вашего компонента.
Вы можете прочитать мой вопрос / ответ об этом поле , если вас интересует.

2) Ветвь (if/else) в логике означает, что у вас есть несколько сценариев.
Под разными сценариями подразумеваются, как правило, разные методы испытаний и значимые имена.
Вы также можете положиться на данную / когда / затем идиому.

3) Поскольку в вашем тесте входная информация для ветви предоставляется макетом, это также означает, что вы будете регистрировать различные варианты поведения для макета в каждом методе теста.

4) UserService не нуждается в насмешках. Это должно быть значение, возвращаемое макетом, а не самим макетом. Здесь вы должны издеваться над Map.

5) Вы проверяете UserFactory, поэтому вы должны назвать его UserFactoryTest.

Например:

@RunWith(MockitoJUnitRunner.class)
public class UserFactoryTest {

    @Mock
    private Map<String, User> UserMap;

    @InjectMocks
    private UserFactory UserFactory;

    private String userId = "123";


    @Test
    public void getUser(){
       when(UserMap.get(userId)).thenReturn(userService);
       userService actual = userServiceFactory.getUser(userId);
       assertEquals(UserMap.get(userId), actual);
    }


    @Test
    public void getUser_with_unknown_userId(){
        Assertions.assertThrows(IllegalArgumentException.class, 
                            ()->  userServiceFactory.getUser(userId));
    }

}

Вы замечаете, что во втором случае я не регистрирую никакого поведения для макета.
По умолчанию Mockito возвращает null, и на самом деле это то, что мне нужно, чтобы спровоцировать исключение. Так что все в порядке.
Также обратите внимание, что я написал утверждение, полагаясь на библиотеку JUnit 5, а не на библиотеку JUnit 4, которую вы, похоже, используете в соответствии с используемым бегуном.
Вы должны рассмотреть возможность перехода на JUnit 5 для новых тестов.

...