测试方法mockito与春天的背景

时间:2018-06-07 06:30:36

标签: java unit-testing mocking

您好我有一种方法可以将人员添加到团队中。我想为这个方法写一个测试,但是我在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 :(得分:1)

你的问题是行

<include resource="org/springframework/boot/logging/logback/defaults.xml" />

在您正在测试的方法中。在Person person = personRepository.getOne(personId); Team team = teamRepository.getOne(teamId); 的单元测试中,您不希望测试两种addPersonsToTeams方法的行为。这就是使用Mockito的重点 - 您可以为单个方法编写单元测试,而不会影响测试的其他方法。

这意味着您需要指定这两个调用将返回的内容。这是“存根”调用,只有在调用方法的对象是间谍或模拟时才能执行此操作。所以在Mockito,你可能会写类似

的东西
getOne

这意味着每当调用doReturn(myPerson).when(mockPersonRepository).getOne(personId); 时,都不会发生任何事情。该方法本身不会运行,Mockito会立即返回mockPersonReposity.getOne(personId)

这就是你想要的技术。因此,当您在测试中添加存根时,它可能看起来像这样。

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
  • Mockito有另一种用于存根的语法,它有时会起作用,但并非总是如此。它看起来像L。许多人发现这更具可读性,但它有很多缺点。我建议永远不要使用(实际上永远不会学习)这个其他语法。我的答案to this question概述了我的理由。