grails Grails 单元测试中的应用程序访问

Posted

技术标签:

【中文标题】grails Grails 单元测试中的应用程序访问【英文标题】:grailsApplication access in Grails unit Test 【发布时间】:2012-11-30 12:34:40 【问题描述】:

我正在尝试为使用 grailsApplication.config 进行一些设置的服务编写单元测试。似乎在我的单元测试中,服务实例无法访问其设置的配置文件(空指针),而当我运行“run-app”时它可以访问该设置。如何在单元测试中配置服务以访问 grailsApplication 服务。

class MapCloudMediaServerControllerTests 

    def grailsApplication

    @Before
    public void setUp()
        grailsApplication.config= 
        '''
   video
   location="C:\\tmp\\"  // or shared filesystem drive for a cluster

    yamdi
        path="C:\\FFmpeg\\ffmpeg-20121125-git-26c531c-win64-static\\bin\\yamdi"  
         

    ffmpeg  
        fileExtension = "flv"  // use flv or mp4
        conversionArgs = "-b 600k -r 24 -ar 22050 -ab 96k"
        path="C:\\FFmpeg\\ffmpeg-20121125-git-26c531c-win64-static\\bin\\ffmpeg"
        makethumb = "-an -ss 00:00:03 -an -r 2 -vframes 1 -y -f mjpeg"
    

    ffprobe 
        path="C:\\FFmpeg\\ffmpeg-20121125-git-26c531c-win64-static\\bin\\ffprobe" 
        params=""
    

    flowplayer 
        version = "3.1.2" 
    

    swfobject 
        version = "" 

    qtfaststart 
        path= "C:\\FFmpeg\\ffmpeg-20121125-git-26c531c-win64-static\\bin\\qtfaststart" 
     
   '''
    

@Test
    void testMpegtoFlvConvertor() 

        log.info "In test Mpg to Flv Convertor function!"

        def controller=new MapCloudMediaServerController()
        assert controller!=null

        controller.videoService=new VideoService()  
        assert controller.videoService!=null

        log.info "Is the video service null? $controller.videoService==null"

        controller.videoService.grailsApplication=grailsApplication

        log.info "Is grailsApplication null? $controller.videoService.grailsApplication==null"

        //Very important part for simulating the HTTP request
        controller.metaClass.request = new MockMultipartHttpServletRequest()
        controller.request.contentType="video/mpg"
        controller.request.content= new File("..\\MapCloudMediaServer\\web-app\\videoclips\\sample3.mpg").getBytes()

        controller.mpegtoFlvConvertor()

        byte[] videoOut=IOUtils.toByteArray(controller.response.getOutputStream())
        def outputFile=new File("..\\MapCloudMediaServer\\web-app\\videoclips\\testsample3.flv")
        outputFile.append(videoOut) 
    

【问题讨论】:

您在此测试中有 TestFor 或任何注释吗?不要重新声明 grailsApplication,mock 自带注解。见GrailsUnitTestMixin yes 它有 @TestFor 注释。我删除了“def grailsApplication”,但在 grailsApplication 对象上得到了 null 消息。顺便说一句,我正在使用 Grail 2.1。 你能发布堆栈跟踪吗?另外,我不确定你是否可以这样声明配置,因为它是 ConfigObject 的一个实例。我会做一个测试,看看你是否需要使用 ConfigSlurper。 我认为它无法解析配置数据。这是错误消息:Cannot cast object 'video ...... ' with class 'java.lang.String' to class 'groovy.util.ConfigObject' 看我的编辑,在这种情况下你需要使用 ConfigSlurper。 【参考方案1】:

如果您使用@TestFor Grails (2.0) 已经为您模拟 grailsApplication,只需设置您的配置,但不要声明 grailsApplication。这样做会覆盖模拟实例。

@TestFor(MyService)
class MyServiceTests 

  @Before
  public void setUp() 
    grailsApplication.config.something = "something"
  

  @Test
  void testSomething() 
    MyService service = new MyService()
    service.grailsApplication = grailsApplication
    service.doSomething()
  



编辑

您声明了String,要添加到配置中,您必须解析它。请参阅here 示例。

基本上您使用ConfigSlurper().parse() 来获取ConfigObject,并使用grails.config.merge() 将内容添加到配置中。

【讨论】:

我之前做过服务单元测试,它正在工作。现在我在控制器中使用了该服务。我想测试使用该服务的控制器。似乎我无法设置 grailsApplication(用于服务)来测试控制器功能。有什么建议吗? 像这个例子一样创建服务,直接在你的控制器实例中设置。 我按照您提到的方式进行了操作,但收到消息“无法在空对象上设置属性 'config'”。 我也有这个问题,因为 groovy.lang.MissingPropertyException: No such property: grailsApplication for class: MyService【参考方案2】:

使用DefaultGrailsApplication 构建 grailsApp 可以。

class ZazzercodeUnitTestCase extends GrailsUnitTestCase 
    def grailsApplication = new org.codehaus.groovy.grails.commons.DefaultGrailsApplication()
    def chortIndex= grailsApplication.config.zazzercode.chortIndex

【讨论】:

【参考方案3】:

转到http://ilikeorangutans.github.io/2014/02/06/grails-2-testing-guide

Grails 的配置通常通过注入的实例来访问 GrailsApplication 使用 config 属性。 Grails 注入 GrailsApplication 放到单元测试中,所以你可以直接访问它:

@TestMixin(GrailsUnitTestMixin)
class MySpec extends Specification         
    private static final String VALUE = "Hello"
    void "test something with config"() 
        setup:
        // You have access to grailsApplication.config so you can 
        //modify these values as much as you need, so you can do
        grailsApplication.config.myConfigValue = VALUE

        assert:             
        grailsApplication.config.myConfigValue == VALUE
    


【讨论】:

以上是关于grails Grails 单元测试中的应用程序访问的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Grails 单元测试中使用 Spock 模拟 passwordEncoder

Grails 3:单元测试拦截器:不会在拦截器中停止

Grails 2.3 使用 IVY 解析器进行单元测试

IntelliJ IDEA 的零覆盖:带有 Spock 单元测试的 Grails

单元测试控制器时无法模拟 Grails 服务方法 - MissingMethodException

Grails 域标准验证器:我应该测试还是不测试?