Вопрос-ответ

How to mock void methods with Mockito

Как имитировать методы void с помощью Mockito

Как имитировать методы с возвращаемым типом void?

Я реализовал шаблон observer, но я не могу имитировать его с помощью Mockito, потому что я не знаю как.

И я пытался найти пример в Интернете, но безуспешно.

Мой класс выглядит следующим образом:

public class World {

List<Listener> listeners;

void addListener(Listener item) {
listeners.add(item);
}

void doAction(Action goal,Object obj) {
setState("i received");
goal.doAction(obj);
setState("i finished");
}

private string state;
//setter getter state
}

public class WorldTest implements Listener {

@Test public void word{
World w= mock(World.class);
w.addListener(this);
...
...

}
}

interface Listener {
void doAction();
}

Система не запускается с помощью mock.

Я хочу показать вышеупомянутое состояние системы. И сделать утверждения в соответствии с ними.

Переведено автоматически
Ответ 1

Взгляните на Mockito API docs. Как упоминается в связанном документе (пункт № 12), вы можете использовать любое из doThrow(),doAnswer(),doNothing(),doReturn() семейства методов из Mockito Framework для имитирования методов void.

Например,

Mockito.doThrow(new Exception()).when(instance).methodName();

или, если вы хотите объединить это с последующим поведением,

Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();

Предполагая, что вы смотрите на имитацию установщика setState(String s) в мире классов, приведенный ниже код использует doAnswer метод для имитирования setState.

World mockWorld = mock(World.class); 
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockWorld).setState(anyString());
Ответ 2

I think I've found a simpler answer to that question, to call the real method for just one method (even if it has a void return) you can do this:

Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();

Or, you could call the real method for all methods of that class, doing this:

<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);
Ответ 3

Adding to what @sateesh said, when you just want to mock a void method in order to prevent the test from calling it, you could use a Spy this way:

World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();

When you want to run your test, make sure you call the method in test on the spy object and not on the world object. For example:

assertEquals(0, spy.methodToTestThatShouldReturnZero());
Ответ 4

The solution of so-called problem is to use a spy Mockito.spy(...) instead of a mock Mockito.mock(..).

Spy enables us to partial mocking. Mockito is good at this matter. Because you have class which is not complete, in this way you mock some required place in this class.

java unit-testing