当前位置: 首页 > 知识库问答 >
问题:

Spock:用GroovyMock调用不需要的真实方法

尹承业
2023-03-14

我有一个这样的测试

def "fileField should be set for each line batch"(){
    given:
    LuceneEngine le = new LuceneEngine()
    le.indexWriter = Mock( IndexWriter ){
        addDocument(_) >> null 
    }
    le.currentFilename  = 'dummy filename'
    le.fileField = GroovyMock( TextField )

    when:
    le.processLineBatch([ 'dummy text' ], 0 )

    then:
    1 * le.fileField.setStringValue( 'dummy filename' ) >> null         

}
def processLineBatch( List lineBatch, int deliveryNo ) {
    String lDocText = lineBatch.join( '\n' ).trim()
    textField.setStringValue( lDocText )
    fileField.setStringValue( currentFilename )
    indexWriter.addDocument( singleLDoc )
}

lucene6中的textfield在这里...从中可以链接到超类字段并查看setStringValue是(非final)public void

共有1个答案

何长恨
2023-03-14

事实上,你基本上已经问了同样的问题,你甚至接受了我的回答!您需要使用全局Groovy模拟:

package de.scrum_master.stackoverflow

import org.apache.lucene.document.TextField
import org.apache.lucene.index.IndexWriter
import org.apache.lucene.index.IndexableField

class LuceneEngine {
  TextField textField
  TextField fileField
  IndexWriter indexWriter
  String currentFilename
  Iterable<? extends IndexableField> singleLDoc

  def processLineBatch(List lineBatch, int deliveryNo) {
    String lDocText = lineBatch.join('\n').trim()
    textField.setStringValue(lDocText)
    fileField.setStringValue(currentFilename)
    indexWriter.addDocument(singleLDoc)
  }
}
package de.scrum_master.stackoverflow

import org.apache.lucene.document.TextField
import org.apache.lucene.index.IndexWriter
import spock.lang.Specification

class LuceneEngineTest extends Specification {
  def "fileField should be set for each line batch"() {
    given:
    LuceneEngine le = new LuceneEngine()
    le.indexWriter = Mock(IndexWriter) {
      addDocument(_) >> null
    }
    le.currentFilename = 'dummy filename'
    // Assign this to le.textField or le.fileField if you like, it does not
    // make a difference because the Groovy mock is GLOBAL
    GroovyMock(TextField, global: true)

    when:
    le.processLineBatch(['dummy text'], 0)

    then:
    1 * le.fileField.setStringValue('dummy filename') >> null
  }
}

至于为什么需要在这里使用全局模拟,我无法解释。这是斯波克邮件列表的问题。我又做了你的工作,并在那里发了一个问题。

 类似资料:
  • 我试图为一个类编写一个单元测试,这个类使用带有库中的的Google vision API。问题是,由于某种原因,我的模拟仍然调用真正的方法,然后抛出一个NPE,这破坏了我的测试。我以前从未在模拟上见过这种行为,我想知道我是不是做错了什么,是不是Spock/Groovy中有bug,还是与Google lib有关?

  • 假设我有以下代码: 是否有可能在中调用来自的的编译器错误?我知道实际上你会把那个方法放在构造函数中,但这个问题是出于好奇。

  • 但是如果我从ClassUnderTest运行methodUnderTest: 它抛出了一个ClassWithStatic的真实实例,该实例在其实例Method中失败。

  • 当静态类在其他Java类中使用时,Groovy测试不会为该类创建模拟。下面的代码片段证明了这一点 测试中的Java类: 带有静态方法的Java类: 失败的Groovy测试:

  • 我需要做一些异步方法。不要等到它执行。我尝试未来,但它没有帮助。 但这里的日志: 正如您所见,日志打印“onFailedLogonSimulation:after”是在10秒后调用的。但我需要日志在“OnFailedLogonSimulation:before”之后每天打印。不等待单元异步方法调用完成。

  • 在下面的代码中,我编写了两种方法: 将变量定义为String的变量 根据键入的内容返回两种不同结果的方法 我有一个名为的变量在中,而中的参数被命名为。在中,我使用而不是-为什么这样工作? 调用方法时,参数是否无关紧要? 我知道,当输入一个返回某个内容的方法时,必须对其进行定义,参数进一步定义该方法将要处理的内容,因此,我假设,当从另一个方法调用所述方法时,必须使用相同的参数,但情况似乎并非如此。