Вопрос по java, generics, mockito – фиктивный метод с универсальным и расширяется в возвращаемом типе

15

Можно ли смоделировать (с помощью mockito) метод с подписьюSet<? extends Car> getCars() без предупреждения? Я пытался

<code>XXX cars = xxx;
when(owner.getCars()).thenReturn(cars);
</code>

но как бы я ни объявилcars Я всегда получаю ошибку компиляции. например, когда я заявляю, как это

<code>Set<? extends Car> cars = xxx
</code>

я получаю стандартную ошибку компиляции обобщенного / мокито

<code>The method thenReturn(Set<capture#1-of ? extends Car>) in the type OngoingStubbing<Set<capture#1-of ? extends Car>> is not applicable for the arguments (Set<capture#2-of ? extends Car>)
</code>
Какую ошибку компиляции вы получаете, можете ли вы скопировать / вставить? miks
Предупреждение, сбой компиляции и исключения - это разные вещи ... Я думаю, вы можете их здесь запутать. Beau Grantham
Я пытался объяснить все точно. так еще раз проясним. Я хочу, чтобы мой код компилировался. Также я хотел бы, чтобы в этом коде не было предупреждений и@SupressWarning. Я никогда не упоминал ничего об исключениях. надеюсь, это поможе piotrek
Возможная копия / Stackoverflow.com вопросы / 7366237 / ... Mike Rylander
Я согласен, что это дубликат / Stackoverflow.com вопросы / 7366237 / ... за исключением того, что он на самом деле новее, так что это не дубликат. Но у него больше ответов. И, возможно, более ясное название. Don Willis

Ваш Ответ

1   ответ
31

Тестируемая система:

public class MyClass {
  Set<? extends Number> getSet() {
    return new HashSet<Integer>();
  }
}

и контрольный пример:

import static org.mockito.Mockito.*;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

public class TestMyClass {
  @Test
  public void testGetSet() {
    final MyClass mockInstance = mock(MyClass.class);

    final Set<Integer> resultSet = new HashSet<Integer>();
    resultSet.add(1);
    resultSet.add(2);
    resultSet.add(3);

    doReturn(resultSet).when(mockInstance).getSet();

    System.out.println(mockInstance.getSet());
  }
}

Никаких ошибок или предупреждений не требуется

Просто, но работает. Я ненавижу этот синтаксис по двум причинам. читаемость и тот факт, что мы полностью отказались от использования дженериков вообще. Неужели это невозможно сделать с помощью дженериков? piotrek
Я понимаю вашу неприязнь к синтаксису, я также предпочитаю синтаксис «когда-то». Я не понимаю, что вы имеете в виду, что невозможно сделать это с помощью дженериков. Tom Tresansky
Верно. Как сказано в документации: «Остерегайтесь того, когда (объект) всегда рекомендуется для создания заглушек, поскольку он является аргументом типобезопасным и более читаемым (особенно при обработке последовательных вызовов)». Но так как метод when () возвращает обобщенный OngoingStubbing <T>, где T - это тип метода, предоставленного для when (), и затем требует вызова thenReturn (T) ... Я не думаю, что есть какой-либо способ избежать этой ошибки компилятора, это должно произойти. Не могли бы вы избавиться от подстановочного знака в методе, который вы используете? Превратить его в параметр класса? Tom Tresansky
Я говорю о параметре doReturn. это объект. он никак не связан с типом, который должен быть возвращен. нет проверки типов во время компиляции. однако, если я не получу лучшего ответа, я возьму этот, потому что, как я уже сказал - это работает piotrek
Смотри ответ здесь Stackoverflow.com / а / 19119230/193606 для безопасной альтернативы Josh

Похожие вопросы