Проблема с ArgumentCaptor и последовательным вызовом одних и тех же методов (ошибка или функция?) - PullRequest
4 голосов
/ 26 июля 2010

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

List<Dummy> mList = mock(List.class);
Dummy dummy = new Dummy();
when(mList.get(anyInt())).thenReturn(dummy);

Dummy d = mList.get(12);
d.setName("John");
mList.add(d);

Dummy g = mList.get(10);
g.setName("Ben");
mList.add(g);
...

verify(mymock, times(3)).doStuff(captor.capture)); 
assertEquals("John", captor.getAllValues().get(0).getName()); 
assertEquals("Ben", captor.getAllValues().get(1).getName()); 
assertEquals("Don", captor.getAllValues().get(2).getName()); 

Значение getName () всегда имеет значение «Don».Я также пытался использовать InOrder, с тем же результатом.

Функция (и меня глупость) или ошибка?

Чтобы лучше объяснить проблему, я создал вариант использования: http://pastebin.com/RE1UzJ4F

Приветствия

Ответы [ 3 ]

2 голосов
/ 03 июля 2012

Iwein правильно; однако в некоторых ситуациях (например, во встроенных системах) недостаточно памяти, и вы не хотите использовать или не можете использовать неизменяемость.

Обходной путь, который я нашел, состоит в том, чтобы использовать разные mock для каждого вызова, а затем проверить список mock для каждого вызова.

List<Mock> mocks = new ArrayList<Mock>();
...init list w/ mocks using for loop...
List<Object[]> expectedArgs = new ArrayList<Object[]>();
..init list w/ desired args...

mocks.get(0).callMethod(1, 2);
 ...do that some more...

for(int i = 0; i < mocks.size(); i++) {
     Object[] desiredArgs = expectedArgs.get(i);
     verify(mocks.get(i)).callMethod((int) desiredArgs[0], (int) desiredArgs[1]);
 }

Это не так красиво, но вам не нужно делать так, чтобы ваши классы были неизменными.

2 голосов
/ 26 июля 2010

Документ Java для ArgumentCaptor предлагает то, что вы пытаетесь, так что я бы сказал, что это ошибка. Тем не менее, это ошибка в вашем коде.

Проблема в том, что вы меняете имя одного и того же манекена при каждом вызове setName (..). Я бы посоветовал вам сделать Dummy неизменным и избегать сеттеров везде, где можете. Это позволит избежать этих типов ошибок.

Если вы не можете сделать свой Dummy неизменным, чтобы вызвать проблему, вы должны, по крайней мере, передавать разные экземпляры из каждого экземпляра. Doing

when(mList.get(anyInt())).thenReturn(new Dummy(), new Dummy(), new Dummy());

Устранит проблему.

1 голос
/ 11 июля 2012

У меня была эта проблема, и в итоге я использовал atLeastOnce, вот так:

private ActionRequest getRequestedAction() {
    ArgumentCaptor<ActionRequest> captor = ArgumentCaptor.forClass(ActionRequest.class);
    verify(adapter, atLeastOnce()).requestAction(captor.capture());
    return captor.getValue();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...