Метод испытания mockito с пружинным контекстом - PullRequest
0 голосов
/ 07 июня 2018

Здравствуйте, у меня есть метод добавления людей в команды.Я хочу написать тест для этого метода, но я новичок в тесте junit / mockito, поэтому у меня много проблем: Это мой метод добавления:

@Transactional
public void addPersonsToTeams(Long teamId, Long personId) {
    Assert.notNull(personId, "Object can't be null!");
    Assert.notNull(teamId, "Object can't be null!");
    try {
        Person person = personRepository.getOne(personId);
        Team team = teamRepository.getOne(teamId);
        person.getTeams().add(team);
        personRepository.save(person);
    } catch (Exception e) {
        throw new CreateEntityException();
    }

}

Существует связь между этими двумя объектами (люди /команды) А это мой тестовый код, но он не работает:

@Test
    public void shouldAddPersonToTeam(){
        Team team = new Team(1l, "TestCase1", "Description1", "Krakow", 12);
        Person person = new Person(1L, "jan", "mucha", "krakow", "email1@onet.com", "Programing", "Developer");

        teamService.createTeam(mapper.map(team, TeamDto.class));
        personService.addPerson(mapper.map(person, PersonDto.class));

        teamService.addPersonsToTeams(team.getId(), person.getId());

        verify(teamRepository, times(1)).save(team);
        verify(personRepository, times(1)).save(person);


    }

Макет конфигурации:

public class TeamServiceTest {
    private TeamService teamService;
    private ModelMapper mapper;
    private PersonService personService;

    @Mock
    private TeamRepository teamRepository;
    private PersonRepository personRepository; //-this is never assigned :/

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        this.mapper = new ModelMapper();
        teamService = new TeamService(teamRepository, this.mapper);
        personService = new PersonService(personRepository, this.mapper);

    }

1 Ответ

0 голосов
/ 07 июня 2018

Ваша проблема - строки

Person person = personRepository.getOne(personId);
Team team = teamRepository.getOne(teamId);

в методе, который вы тестируете.В своем модульном тесте для addPersonsToTeams вы не хотите проверять поведение двух getOne методов.В этом весь смысл использования Mockito - вы можете писать модульные тесты для отдельных методов без влияния других методов на тесты.

Это означает, что вам нужно указать, что будет возвращено этими двумя вызовами.Это «заглушение» вызовов, и вы можете сделать это только в том случае, если объекты, для которых вызываются методы, являются либо шпионами, либо поддельными.Так что в Mockito вы можете написать что-то вроде

doReturn(myPerson).when(mockPersonRepository).getOne(personId);

, что означает, что когда бы ни вызывали mockPersonReposity.getOne(personId), ничего не происходило.Сам метод не запускается, и Mockito сразу же возвращает myPerson.

Это техника, которую вы хотите здесь.Поэтому, когда вы добавляете заглушку в свой тест, это может выглядеть примерно так:

@Mock private TeamRepository mockTeamRepository; 
@Mock private PersonRepository mockPersonRepository;

@Before 
public void setUp() { 
    MockitoAnnotations.initMocks(this); 
    mapper = new ModelMapper(); 
    teamService = new TeamService(mockTeamRepository, mapper); 
    personService = new PersonService(mockPersonRepository, mapper);
}

@Test
public void shouldAddPersonToTeam(){
    Team team = new Team(1L, "TestCase1", "Description1", "Krakow", 12);
    Person person = new Person(1L, "jan", "mucha", "krakow", "email1@onet.com", "Programing", "Developer");

    doReturn(team).when(mockTeamRepository).getOne(1L);
    doReturn(person).when(mockPersonRepository).getOne(1L);

    teamService.createTeam(mapper.map(team, TeamDto.class));
    personService.addPerson(mapper.map(person, PersonDto.class));

    teamService.addPersonsToTeams(team.getId(), person.getId());

    verify(mockTeamRepository).save(team);
    verify(mockPersonRepository).save(person);
}

Всего несколько дополнительных точек.

  • Стоит использовать префикс mock наимена переменных ваших фиктивных объектов, просто чтобы отслеживать, какие переменные являются фиктивными, а какие нет.
  • Нет необходимости записывать times(1) в ваших verify вызовах - режим проверки по умолчанию:times(1), так что ваш код будет менее загроможденным, если вы просто его пропустите.
  • Не используйте строчные буквы l для long литерала - 1l выглядит слишком похоже на 11,Для удобства чтения всегда используйте заглавные буквы L.
  • У Mockito есть другой синтаксис для заглушки, который иногда работает, но не всегда.Похоже when(mockPersonRepository.getOne(personId)).thenReturn(person);.Многие люди находят это более читабельным, но у него есть много недостатков.Я рекомендую никогда не использовать (и фактически никогда не изучать) этот другой синтаксис.Причины этого изложены в моем ответе на этот вопрос .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...