Как вернуть новый экземпляр каждый раз, когда вызывается doReturn? - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть следующий тестовый пример:

ClassPathResource resource = new ClassPathResource(...);
doReturn(resource.getInputStream()).when(someMock).getInputStream();

, где я читаю некоторый ресурс и возвращаю его в своем тесте. Этот метод вызывается с некоторой неопределенностью асинхронным, запланированным образом в реальном производственном коде - поэтому я не имею полного контроля над тем, сколько раз он вызывается точно , хотя возвращаемые данные всегда одинаковы ( или должно быть).

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

Я явно делаю не wi sh, чтобы синхронно вызывать его в контексте теста, и использую Awaitility.await() для проверки таких сценариев ios, поэтому, к сожалению, это не вариант для меня.

Теперь, «тупой» способ потенциально исправить это что-то вроде следующего:

doReturn(resource.getInputStream()).doReturn(resource.getInputStream()).<...>.when(someMock).getInputStream();

Но это все еще не решает реальную проблему и в лучшем случае является бинтом.

Я действительно ожидал, что сработает что-то вроде следующего:

ClassPathResource resource = new ClassPathResource(...);
doReturn(resource.call().getInputStream()).when(someMock).getInputStream();

, но вы к сожалению, это также извлекает базовый поток только один раз.

Как я могу предоставить экземпляр fre sh при каждом вызове doReturn()? Может ли mockito это сделать? Есть ли альтернативный подход к тому, что я sh должен сделать?

1 Ответ

1 голос
/ 01 апреля 2020

Я не совсем уверен, что согласен с тем, что вы просите.

Сначала вы делаете ClassPathResource resource = new ClassPathResource(...);, что, как я полагаю, - вещь разовая. И тогда вы возвращаете resource.getInputStream() для каждого вызова. По определению, вы не можете иметь несколько экземпляров - вы просите об одном и пытаетесь сделать другое. Так чего же вы хотите? Вы можете использовать некоторые вопросы реструктуризации. Кроме того, что вы делаете с ClassPathResource в модульном тесте в первую очередь?

Тем временем, лучшее, что я могу догадаться о том, что вы хотите, это наиболее буквальная интерпретация вашего вопроса, которую я могу получить и полностью игнорируя любой и весь псевдо-код (потому что он полностью противоречит вашему вопросу). То есть вам нужен совершенно отдельный экземпляр InputStream для каждого вызова метода. Эта часть проста.

Mockito.doAnswer(new Answer<InputStream>() {
            @Override
            public InputStream answer(InvocationOnMock invocation)
                    throws Throwable {
                return Mockito.mock(InputStream.class);
            }
        }).when(resource.getInputStream());
...