Я пытаюсь использовать Mockito ArgumentCapture
для извлечения общего аргумента, но в моем методе используется один и тот же базовый тип, но с разными родовыми аргументами дважды.
Чтобы упростить пример, я написал тест, отличный от моего кода, но с той же проблемой:
@Captor private ArgumentCaptor<ArrayList<String>> stringl;
@Captor private ArgumentCaptor<ArrayList<Boolean>> booleanl;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
} //setup
@Test
public void test()
{
Foo foo = mock(Foo.class);
List<String> stringList = new ArrayList<String>();
List<Boolean> booleanList = new ArrayList<Boolean>();
foo.doSomething(stringList);
foo.doSomething(booleanList);
verify(foo).doSomething(stringl.capture());
verify(foo).doSomething(booleanl.capture());
} //test
private static class Foo
{
public <T> void doSomething(List<T> list){}
}
Выполнение теста вызывает следующую ошибку:
org.mockito.exceptions.verification.TooManyActualInvocations:
foo.doSomething(<Capturing argument>);
Wanted 1 time:
-> at test(Test.java:19)
But was 2 times. Undesired invocation:
-> at test(Test.java:21)
Чтобы увидеть, что происходит, я добавил times(2)
к методам проверки, а затем проверил захват аргументов. Оба выбрали второй вызов, означающий, что я никогда не смог бы захватить первый аргумент типа List<String>
.
Есть ли способ заставить ArgumentCapture
распознавать разные общие типы для одного и того же базового типа, т.е. Различать List<Boolean>
и List<String>
?
Приветствия, Алексей Синий
Не использовать существующий класс ArgumentCaptor
. Из-за стирания типа эта информация теряется. Я предлагаю вам использовать один захват и получить аргумент, переданный во всех вызовах. Затем вы можете проверить, что он был вызван в первый раз с List<String>
а во второй раз - List<Boolean>
. Конечно, вы сделаете это, проверив содержимое списков.
Альтернативой может быть введенный ArgumentCaptor
@Captor
private ArgumentCaptor<List<Person>> argumentCaptor;
http://blog.jdriven.com/2012/10/mockito-using-argumentcaptor-for-generic-typed-collections/
Мои изменения, чтобы исправить это, были:
@Captor private ArgumentCaptor<ArrayList<?>> aList;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
} //setup
@Test
public void test()
{
Foo foo = mock(Foo.class);
String testString = "Hello Test";
Boolean testBoolean = true;
List<String> stringList = new ArrayList<String>();
stringList.add(testString);
List<Boolean> booleanList = new ArrayList<Boolean>();
booleanList = testBoolean;
foo.doSomething(stringList);
foo.doSomething(booleanList);
//verify to capture and assertion that it happened twice
verify(foo, times(2)).doSomething(aList.capture());
//Get all captured values from the verified invocation
List<ArrayList<?>> args aList.getAllValues();
//verify first list, should be String
assertEquals("TestString assertion wrong", testString, args.get(0).get(0));
//verify second list, should be Boolean
assertEquals("TestBoolean assertion wrong", testBoolean, args.get(1).get(0));
} //test
private static class Foo
{
public <T> void doSomething(List<T> list){}
}
Для меня я пытаюсь сделать один и тот же массаж ошибок два раза.
Если вы пытаетесь проверить тот же массаж, тогда вы должны использовать метод "times" import static org.mockito.Mockito.times
;
verify(anyFakeObject,times(num)).method(parmeter);
где numb - подсчет для такого же массажа.