Как я могу использовать Спока Шпиона? - PullRequest
0 голосов
/ 11 марта 2019

Я пытался использовать Spy test, но он не работал.Следующий класс - Sut.

public class FileManager {
    public int removeFiles(String directory)    {
        int count = 0;
        if(isDirectory(directory))  {
            String[] files = findFiles(directory);
            for(String file : files)    {
                deleteFile(file);
                count++;
            }
        }
        return count;
    }

    private boolean isDirectory(String directory) {
        return directory.endsWith("/");
    }

    private String[] findFiles(String directory) {
        // read files from disk.
        return null;
    }

    private void deleteFile(String file)    {
        // delete a file.
        return;
    }
}

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

class SpyTest extends Specification  {
def "Should return the number of files deleted"()   {
    given:
    def fileManager = Spy(FileManager)
    1 * fileManager.findFiles("directory/") >> { return ["file1", "file2", "file3", "file4"] }
    fileManager.deleteFile(_) >> { println "deleted file."}

    when:
    def count = fileManager.removeFiles("directory/")

    then:
    count == 4
}

Но я получил исключение NullPointerException.

java.lang.NullPointerException
at example.spock.mock.FileManager.removeFiles(FileManager.java:8)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.spockframework.mock.runtime.CglibRealMethodInvoker.respond(CglibRealMethodInvoker.java:32)
at org.spockframework.mock.runtime.MockInvocation.callRealMethod(MockInvocation.java:60)
at org.spockframework.mock.CallRealMethodResponse.respond(CallRealMethodResponse.java:29)
at org.spockframework.mock.runtime.MockController.handle(MockController.java:49)
at org.spockframework.mock.runtime.JavaMockInterceptor.intercept(JavaMockInterceptor.java:72)
at org.spockframework.mock.runtime.CglibMockInterceptorAdapter.intercept(CglibMockInterceptorAdapter.java:30)
at example.spock.mock.SpyTest.Should return the number of files deleted(SpyTest.groovy:13)

Это означает, что вызывается реальный метод.Есть ли причина, по которой он не работает?

1 Ответ

0 голосов
/ 12 марта 2019

В Споке вы не можете высмеивать частные методы java-класса.Глядя на ваш FileManager, не ясно, почему только removeFiles является публичным, а другие - приватными.Хотя все методы связаны с управлением файлами.Возможные решения:

  1. Сделайте остальные методы FileManager общедоступными.Таким образом, Спок будет работать, и FileManager фактически станет файловым менеджером, а не просто средством удаления файлов
  2. Разложить FileManager на различные компоненты.Таким образом, вы можете смоделировать эти компоненты отдельно и добавить их в «средство для удаления файлов».В основном вы уже разложили свой код на уровне методов.Но частные методы Java не могут быть посмешищами в Spock .А декомпозиция класса может оказаться непосильной, поскольку FileManager выглядит как-то связно со всеми своими операциями
  3. Используйте другие тестовые / макетные среды, которые могут высмеивать частные методы.Например, mockito и powermock.Тем не менее, имитация частных методов - наихудший вариант, потому что в долгосрочной перспективе он может повредить возможности сопровождения всей кодовой базы, если выйдет из-под контроля
...