Насмешливый заводной новый File.eachFile () - PullRequest
1 голос
/ 17 февраля 2011

У меня проблемы с подделкой file.eachFile () {}.

Я пытаюсь смоделировать файлы, которые возвращаются из file.eachFile {} - я не хочу проверятьсодержимое реального каталога на моем диске.

Я не понимаю, как я могу добиться этого, используя Спок (насколько я понимаю, он используется больше для проверки подлинности).

* 1008Итак, я решил использовать «родные» Groovy фиктивные возможности и MOP .Не повезло.

Например (мне пришлось удалить тип файла, чтобы передать объект в функцию тестирования):

def mockFile = new MockFor(java.io.File)

mockFile.demand.eachFile {[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {it}} 

или (с использованием метакласса):

File mockFile = new File("irrelevant_path")
mockFile.metaClass.eachFile = {[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {it}}

I метод eachFile определен следующим образом:

public static void eachFile(final File self, final Closure closure) throws FileNotFoundException, IllegalArgumentException {
        eachFile(self, FileType.ANY, closure);
    }

Я уже немного нечеткий из всех попыток кодирования, чтобы высмеять это:)

Мне удалось добраться дометод (без исключений времени выполнения), но я не могу фактически увидеть внедрение списка файлов, как определено ранее.

Протестированный метод (для простоты):

folderSourceScripts.eachFile {File currentFile -> ..... }

В Java,Mockito сделает это за минуту, но я где-то читал, что есть некоторые проблемы, связанные с интеграцией с Groovy.Существует проблема при издевательстве над классами, потому что Groovy вызывает Metaclass.

Я видел это здесь .

tim_yates wrote:

def mock = new MockFor(File)
mock.demand.eachFile {
  [new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each { (it) }
}

mock.use {
  new File('.').eachFile {file ->
    println "$file"
  }

Сценарий работает, но при его использовании в тесте есть хитрость.

Как я уже говорил, я использую Spock, а переменная file передается в метод.Поэтому использование его так, как вы написали, вызывает:

groovy.lang.MissingMethodException: No signature of method: groovy.mock.interceptor.MockFor.eachFile() is applicable for argument types: ... 

Я полагаю, это потому, что в коде нет прямого использования File.eachFile () (он не передает макет методу,он ожидает, что макет будет создан в блоке «use»)?

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

when:
    mock.use {
      folderValidator.validate(mock)
    }

then:
    folderValidator.listMissingFiles.size == 3

Проблема с proxyInstance (), которая должна пройтиmock в метод, как показано в примере:

when:
    folderValidator.validate(mockProxy)

then:
    folderValidator.listMissingFiles.size == 3

Когда mock пройден, groovy не может создать экземпляр класса, потому что он не знает, какой конструктор использовать?

org.codehaus.groovy.runtime.metaclass.MethodSelectionException: Could not find which method <init>() to invoke from this list:

  private java.io.File#<init>(java.lang.String, int)
  private java.io.File#<init>(java.lang.String, java.io.File)
  public  java.io.File#<init>(java.lang.String)
  public  java.io.File#<init>(java.net.URI)
  public  java.io.File#<init>(java.io.File, java.lang.String)
  public  java.io.File#<init>(java.lang.String, java.lang.String)

Теоретически это работает, но в этом примере это не получается, возможно, я неправильно его кодирую.Я начал использовать Groovy две недели назад, так что я все еще привыкаю к ​​нему.Спасибо

1 Ответ

2 голосов
/ 18 февраля 2011

tim_yates писал:

def mock = new MockFor(File)
mock.demand.eachFile {
  [new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each { (it) }
}

mock.use {
  new File('.').eachFile {file ->
    println "$file"
  }

Он был прав.Как я уже сказал, я не использовал Groovy так долго (как и Спок).

"Я думаю, это потому, что в коде нет прямого использования File.eachFile () (он не пропускаетмакет метода, он ожидает, что макет будет создан в блоке "use")? "

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

when:

        mock.use {
          folderValidator.validate(new File("."))
        }

then:
        folderValidator.listMissingFiles.size == 3

Решение было простосоздание экземпляра макета класса внутри блока использования.Я думал, что макет создается и будет передан в методе - способ, которым работает Mockito.

Mockito:

File pathScripts;
pathScripts = mock(File.class);
when(pathScripts.list()).thenReturn(listFiles);

someObject.someTestingMethod(pathScripts)

Способ proxyInstance - это макет класса, НО С ПРАВИЛЬНЫМИ КОНСТРУКТОРНЫМИ АРГУМЕНТАМИ !

def mock = new MockFor(File)
mock.demand.eachFile {func ->
  [new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each { func(it) }
}

def mockProxy = mock.proxyInstance(".")

mockProxy.eachFile {file ->
  println "$file"
}

И самой большой ошибкой было отсутствие закрытия в моем издевательском методе:

mockFile.demand.eachFile { **??** [new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {**?**(it)}} 

Итак, спасибо, tim_yates.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...