Я постараюсь дать несколько советов.
1) Здесь я бы не стал издеваться над всей логикой проверки наличия файла, поскольку она является частью поведения тестируемого метода. то есть, когда вы вызываете getFilefromLocation()
.
2) Использовать короткую задержку между повторными попытками — это идея, но достаточно ли этого, чтобы сделать ваш тест надежным?
Не совсем потому, что вы также должны утверждать, что Thread.sleep()
был вызван и с ожидаемым значением. Отсутствие проверки в модульном тесте означает, что любой может удалить Thread.sleep()
в методе getFile()
, и тест все равно пройдет. Вы действительно не хотите этого.
Обратите внимание, что вы не можете легко издеваться над этим: это static
. Вам следует переместить это утверждение в DelayService
, над которым вы могли бы издеваться.
3) На самом деле вы параметризуете retryCount
. Когда вы пишете модульные тесты, вы хотите проверить поведение компонентов в соответствии с вашими требованиями. Таким образом, вы также должны убедиться, что класс, который зависит от getFile(int retryCount)
, эффективно передает ожидаемый параметр: 3
.
Кроме того, если вы не хотите разрешать более определенного числа повторных попыток, вам также нужно добавить эту проверку в метод и утвердите это правило в модульном тесте.
В соответствии с двумя первыми пунктами ваш фактический код может быть реорганизован как:
private FileLocator fileLocator; // added dependency
private DelayService delayService; // added dependency
// constructor to set these dependencies
public MyService(FileLocator fileLocator, DelayService delayService){
...
}
File getFile(int retryCount){
File file;
file = fileLocator.getFilefromLocation(); // -> change here
if(file!=null) return file
if(file==null and retryCount>0){
delayService.waitFor(); // -> other change here
--retryCount;
File filePicked = getFile(retryCount)
}
else return null;
}
Что касается части модульного теста, вы можете использовать Mockito для имитации и смешивания «простых» модульных тестов с параметризованными тестами, поскольку некоторые сценарии имеют аналогичное поведение с разницей в количестве фактических повторных попыток.
Например, повторные попытки 0, 1, 2 и 3 раза и поиск файла — это 4 случая, которые вы можете параметризовать.
И, наоборот, неспособность найти файл не требует параметризации, поскольку все повторные попытки должны выполняться для проверки поведения.
Вот пример кода, основанный на JUnit5 и Mockito (не тестировался), который вы можете адаптировать в соответствии с вашим реальным кодом. Я только что проиллюстрировал параметризованный тест. Другие тестовые примеры не должны быть более сложными для реализации.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.api.Assertions;
import org.mockito.Mockito;
import org.mockito.Mock;
private static final long EXPECTED_DELAY_MN = 1;
private static final long RETRY_COUNT = 3;
@Mock
FileLocator fileLocatorMock;
@Mock
private DelayService delayServiceMock;
MyServiceTest myServiceTest;
public MyServiceTest(){
myServiceTest = new MyServiceTest(fileLocatorMock, delayServiceMock);
}
@ParameterizedTest
@ValueSource(ints = { 0, 1, 2, 3 })
public void getFileThatFailsMultipleTimeAndSuccess(int nbRetryRequired){
// failing find
for (int i=0; i < nbRetryRequired; i++) {
Mockito.when(fileLocatorMock.getFilefromLocation(...)).thenReturn(null);
}
// successful find
File fileByMock = new File(...); //fake file
Mockito.when(fileLocatorMock.getFilefromLocation(...)).thenReturn(fileByock);
File actualFile = myServiceTest.getFile(RETRY_COUNT);
// assertions
Mockito.verify(delayServiceMock, Mockito.times(nbRetryRequired))
.waitFor();
Assert.assertSame(fileByMock, actualFile);
}
}
person
davidxxx
schedule
28.07.2018