Java 带有spring上下文的测试方法mockito
您好,我有一个向团队添加人员的方法。我想为此方法编写一个测试,但我是junit/mockito测试的新手,所以我有很多问题: 这是我的添加方法:Java 带有spring上下文的测试方法mockito,java,unit-testing,mocking,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 nul
@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);
}
你的问题是线路
Person person = personRepository.getOne(personId);
Team team = teamRepository.getOne(teamId);
在你正在测试的方法中。在对addPersonStoreAMS
的单元测试中,您不想测试两个getOne
方法的行为。这就是使用Mockito的全部意义所在——您可以为单个方法编写单元测试,而其他方法的行为不会影响测试
这意味着您需要指定这两个调用将返回什么。这是“存根”调用,只有在调用方法的对象是spies或mock时才可以这样做。所以在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对象的变量名上使用前缀
,这是值得的,只是为了帮助跟踪哪些变量是mock,哪些不是mock
- 在
调用中不必写入验证
——默认验证模式为次(1)
,因此如果不使用它,代码就不会太混乱次(1)
- 对于
literal-long
看起来太像1l
,不要使用小写的11
。为了便于阅读,请始终使用大写字母l
L
- Mockito还有另一种用于存根的语法,这种语法有时有效,但并不总是有效。它看起来像
when(mockPersonRepository.getOne(personId)),然后返回(person)代码>。很多人觉得这更具可读性,但它有很多缺点。我建议永远不要使用(事实上也永远不要学习)这种其他语法。我的答复中概述了我这样做的理由
teamRepository
和personRespository
?@Mock private teamRepository teamRepository;个人知识库@在public void setUp()之前{MockitoAnnotations.initMocks(this);this.mapper=new ModelMapper();teamService=new teamService(teamRepository,this.mapper);personService=new personService(personRepository,this.mapper);}感谢Answare,但在添加代码之后,我有了这个;当()为空时传递给的参数!正确的存根示例:doThrow(newruntimeexception()).when(mock).someMethod();另外,如果您使用@Mock annotation don't miss initMocks()确定,您确定要调用MockitoAnnotations.initMocks(this)代码>?另外,PersonRepository
或TeamRepository
是否会标记为final
?如果是这样,您将无法为它们创建模拟。这可能是错误的。我编辑我的帖子,并在PersonRepository
的声明前面显示我的模拟配置write@mock
,正如我在回答中所显示的那样。Omg当然是愚蠢的错误。但在此之后,我在创建团队对象方面遇到了问题:/com.softwaremind.crew.common.CreateEntityException:创建新团队-失败。对象字段有一个错误