Mockito ArgumentCapture не распознает несколько универсальных типов

1

Я пытаюсь использовать 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>?

Приветствия, Алексей Синий

Теги:
unit-testing
junit
mockito

4 ответа

1
Лучший ответ

Не использовать существующий класс ArgumentCaptor. Из-за стирания типа эта информация теряется. Я предлагаю вам использовать один захват и получить аргумент, переданный во всех вызовах. Затем вы можете проверить, что он был вызван в первый раз с List<String> а во второй раз - List<Boolean>. Конечно, вы сделаете это, проверив содержимое списков.

  • 0
    Спасибо @John, я чувствую себя очень глупо из-за того, что не видел captor.getAllValues () перед рукой. Я изменил свой тест, чтобы проверить (mock, times (2)). DoSomething (), а затем я получаю макеты из списка, переданного обратно, и проверяю содержимое в соответствии с предложением :) Круто.
2

Альтернативой может быть введенный ArgumentCaptor

@Captor
private ArgumentCaptor<List<Person>> argumentCaptor;

http://blog.jdriven.com/2012/10/mockito-using-argumentcaptor-for-generic-typed-collections/

0

Мои изменения, чтобы исправить это, были:

@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){}
}
-4

Для меня я пытаюсь сделать один и тот же массаж ошибок два раза.

Если вы пытаетесь проверить тот же массаж, тогда вы должны использовать метод "times" import static org.mockito.Mockito.times;

verify(anyFakeObject,times(num)).method(parmeter);

где numb - подсчет для такого же массажа.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню