Сопоставление параметров на основе универсальных типов с Mockito - PullRequest
0 голосов
/ 09 ноября 2018

Я ищу способ заставить фиктивную функцию возвращать разные значения в зависимости от общего типа ее параметра. Например, если параметром является любой экземпляр Generic<Foo>, сделайте что-нибудь, а если параметром является любой экземпляр Generic<Bar>, сделайте что-нибудь еще.

Я думал, что смогу сделать это, используя следующий код:

@Mock
private Getter getter;

@Rule
public final Mocks mocks = new Mocks(this);

@Test
public void testSearch(){
    doReturn("Foo<Boolean>").when(getter).getValue(Matchers.<Foo<Boolean>>any());
    doReturn("Foo<String>").when(getter).getValue(Matchers.<Foo<String>>any());
    System.out.println(getter.getValue(new Foo<Boolean>()));
    System.out.println(getter.getValue(new Foo<String>()));
}

public static class Foo<T> {
}

public class Getter {
    <T> String getValue(BumapinRefOdsHandlerTest.Foo<T> foo) {
        return "not-used";
    }
}

Однако код печатает

Foo<String>
Foo<String>

Как правильно сопоставить параметры на основе универсального типа?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Обобщения не доступны напрямую во время выполнения. А в твоем случае

doReturn("Foo<Boolean>").when(getter).getValue(Matchers.<Foo<Boolean>>any());
doReturn("Foo<String>").when(getter).getValue(Matchers.<Foo<String>>any());

закончится вызовом метода с любым параметром типа Foo. Таким образом, последний пень выигрывает, в вашем случае doReturn("Foo<String>").

Если вы измените заказ на

doReturn("Foo<String>").when(getter).getValue(Matchers.<Foo<String>>any());
doReturn("Foo<Boolean>").when(getter).getValue(Matchers.<Foo<Boolean>>any());

вывод будет

Foo<Boolean>
Foo<Boolean>
0 голосов
/ 09 ноября 2018

Вы не можете сделать это. Во время выполнения типы Foo<Boolean> и Foo<String> будут сокращены до одного типа Foo из-за стирания. Например, следующее утверждение будет содержать

assert new Foo<Boolean>().getClass().equals(new Foo<String>().getClass())

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

// Using reflection can recover that FooBoolean used type parameter Boolean
class FooBoolean extends Foo<Boolean> { ... }
// Using reflection on the Method can recover the type parameter of foo
void something(Foo<Boolean> foo) { ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...