Использование Mock для полей, которые являются экземплярами одного класса - PullRequest
0 голосов
/ 24 января 2019

У меня есть классы:

public class Sender {
    private final SomeClass firstField;
    private final SomeClass secondField;
    private Sender(SomeClass firtsField, SomeClass secondField){
        this.firstField = firstField;
        this.secondField = secondField;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class SenderTest{
    @Mock
    private firstField;
    @Mock
    private secondField;
}

Все выглядит отлично, но похоже, что оно вводит одни и те же объекты в два поля или что-то в этом роде. Когда я пытаюсь использовать when (..). ThenReturn () для одного поля, оно устанавливает данные два для другого и vise verse; И самое странное, что он отлично работает в режиме отладки. Что ты можешь сказать?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Это зависит от того, что SomeClass само по себе. Если это объект данных (POJO), стоит создать их в тесте (т.е. заполнить случайными сгенерированными значениями).

Если это услуга. Это может быть знаком для проблемы архитектуры. зачем вам две копии одного и того же сервиса? Возможно, имеет смысл провести рефакторинг.

0 голосов
/ 24 января 2019

У Mockito есть некоторые проблемы с инжекцией в конструктор двух или более полей одного типа. Но он отлично работает, если вы используете сеттерную инъекцию.

Таким образом, вы можете выполнить рефакторинг класса «Отправитель» следующим образом:

    public class Sender {
        private SomeClass firstField;
        private SomeClass secondField;
        public void setFirstField(SomeClass firstField) {
            this.firstField = firstField;
        }
        public void setSecondField(SomeClass secondField) {
            this.secondField= secondField;
        }
    }

Помните, что если у класса есть и конструктор, и сеттеры, Mockito выберет конструктор для инъекции и полностью проигнорирует сеттеры.

Редактировать : если вам определенно необходимо использовать конструктор по какой-либо причине, вы всегда можете макетировать поля вместо использования аннотаций Mockito. Таким образом, в вашем случае Sender останется прежним, а SenderTest будет выглядеть так:

public class SenderTest {

    private SomeClass firstField;
    private SomeClass secondField;

    private Sender sender;

    @Before
    public void setUp() {
        firstField = Mockito.mock(SomeClass.class);
        secondField = Mockito.mock(SomeClass.class);

        sender = new Sender(firstField, secondField);
    }

    @Test
    public void smokeTest() {

    }
}
...