В этом посте мы увидим «продвинутую» технику, используемую в Mockito для возврата того же экземпляра аргумента в макетируемый метод с использованием интерфейса Answer .
Предположим, мы пишем модульные тесты для класса, который управляет классами Person и Job, и в качестве операции он использует класс DAO для вставки класса отношений (M: N) между Person и Job с именем PersonJob .
Например, тестируемый класс будет выглядеть примерно так:
1
2
3
4
5
6
7
|
public PersonJob createPersonJob(Person person, Job job) { .. some job .. PersonJob personJob = new PersonJob(person, job); return this .personJobDao.create(personJob); } |
Так что в этом случае кажется очевидным, что нужно издеваться над personJobDao .
Давайте создадим макет и запишем взаимодействие:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
public class WhenAJobIsAssignedToPerson { @Test public void relationship_should_be_made_persistent() { PersonJobDao personJobDao = mock(PersonJobDao. class ); when(personJobDao.create(any(PersonJob. class ))).thenReturn(???) PersonJobManager personJobManager = new PersonJobManager(); personJobManager.setPersonJobDao(personJobDao); Person person = new Person(); Job job = new Job(); PersonJob personJob = personJobManager.createPersonJob(person, job); assertThat(personJob.getPerson(), is(person)); assertThat(personJob.getJob(), is(job)); } } |
Да, как вы можете видеть, вы не знаете, что возвращать, потому что экземпляр создается тестируемым классом, а в тестовом методе вы не знаете, какой экземпляр создан методом createPersonJob . Чтобы решить эту проблему, вам нужно использовать thenAnswer вместо метода thenReturn :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class WhenAJobIsAssignedToPerson { @Test public void relationship_should_be_made_persistent() { PersonJobDao personJobDao = mock(PersonJobDao. class ); when(personJobDao.create(any(PersonJob. class ))).thenAnswer( new Answer<PersonJob>() { public PersonJob answer(InvocationOnMock invocation) throws Throwable { return (PersonJob) invocation.getArguments()[ 0 ]; } }); PersonJobManager personJobManager = new PersonJobManager(); personJobManager.setPersonJobDao(personJobDao); Person person = new Person(); Job job = new Job(); PersonJob personJob = personJobManager.createPersonJob(person, job); assertThat(personJob.getPerson(), is(person)); assertThat(personJob.getJob(), is(job)); } } |
Обратите внимание, что интерфейс ответа требует от вас реализации метода ответа , который в нашем случае просто возвращает первый аргумент (экземпляр PersonJob ) personJobDao . создать метод.
Теперь мы можем спокойно писать утверждения, не беспокоясь о возвращенном экземпляре.
Ссылка: Ответ с Mockito от нашего партнера JCG Алекса Сото в блоге One Jar To Rule All .