Статьи

Ответ с Мокито

Когда вы пишете модульные тесты , вы должны помнить, чтобы не было зависимостей от внешних компонентов. Чтобы избежать этого, мы используем фиктивные фреймворки, которые для меня самый простой в использовании — это Mockito
В этом посте мы увидим «продвинутую» технику, используемую в 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 .