当前位置: 首页 > 知识库问答 >
问题:

带有spring上下文的测试方法mockito

查宜民
2023-03-14

您好,我有一个将人员添加到团队的方法。我想为此方法编写一个测试,但我是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个答案

田德运
2023-03-14

你的问题是台词

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

在您正在测试的方法中。在addPersonsToTeams的单元测试中,您不想测试两个getOne方法的行为。这就是使用Mockito的全部意义所在——您可以为单个方法编写单元测试,而不需要其他方法的行为影响测试。

这意味着您需要指定这两个调用将返回什么。这是“存根”调用,只有在调用方法的对象是spies或mock时,才能执行此操作。所以在Mockito中,你可以写

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

这意味着每当调用mockPERReposity.getOne(man Id)时,什么都不会发生。该方法本身不会运行,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是值得的,这只是为了帮助跟踪哪些变量是模拟的,哪些不是
  • 无需在验证调用中写入次(1)——默认验证模式次(1),因此,如果不使用它,代码就不会太混乱
  • 不要使用小写字母l来表示长文字,因为l看起来太像11。为了便于阅读,请始终使用大写字母L
  • Mockito还有另一种用于存根的语法,这种语法有时有效,但并不总是有效。它看起来像是when(mockPersonRepository.getOne(personId))。然后返回(人) 。许多人觉得这更具可读性,但它有很多缺点。我建议不要使用(事实上也不要学习)这种其他语法。我对这个问题的回答概述了我这样做的原因

 类似资料:
  • 我想用Mock测试方法,没有spring上下文。我该怎么做?现在,变量返回null。我想设置方法的返回值。

  • 我有一个模块,它调用一个使用bluebirdpromise的方法。这是简化的模块。Cassandra只是一些db调用的包装器,它保证了它们: 我正试图用西农和西农蓝鸟来测试这一点。我取消了Cassandra的查询promise,并让res.sendStatus成为间谍: 我认为使用这些库,存根的then()将被立即调用,而不是异步调用,但情况似乎并非如此。确实调用了res.sendStatus()

  • 嗨,我有一个Spring Boot(2.1.6发行版)应用程序,我正在尝试添加一些简单的集成测试到我的应用程序。首先,我创建了一个基础IntegrationTest类,如下所示: 这是我的测试方法: 有什么建议吗?

  • 我们有一个基于Spring的JUnit测试类,它利用一个内部测试上下文配置类 最近,服务类中引入了新的功能,相关测试应添加到ServiceTest中。但是,这也需要创建不同的测试上下文配置类(现有配置类的内部结构相当复杂,如果可能的话,将其更改为既服务于旧测试又服务于新测试似乎非常困难) 有没有一种方法可以实现一个测试类中的某些测试方法将使用一个配置类,而其他方法将使用另一个?似乎只适用于类级别,

  • 我的(非常基础的)jsp看起来像这样: 我的控制器提供这个: 我尝试过返回mav对象,以及将对象添加到传递的模型中。但无济于事,每当我进入页面时,我都会得到 maven窗口显示“试图在空上下文对象上调用方法getTitle()” 我一定看了无数的教程,我就是不知道我做错了什么。做任何前端的新手也没有帮助! 谢谢!

  • 我正在尝试将Cucumber集成到现有的Spring Boot项目中 当前项目是单个Maven模块 单元测试(不含Spring上下文)和集成测试(含Spring上下文)组合在同一个测试文件夹中。 我想做的是能够调整我的单元测试和集成测试。 但是一旦我添加了依赖项(为了能够在规范旁边运行Spring上下文),它就要求文件夹中的所有测试都用注释。 下面是我的测试套件,配置为获取测试规范。 是否可以将两