2016-04-06 139 views
1

我有一個grails 3項目,我不得不寫一個普通的Spring MVC @RestfulController(用於塊json響應的原因)。無論如何,我試圖爲簡單的控制器操作寫一個簡單的Spock單元測試。它們在IDEA內部運行良好,但是在命令行上它們失敗,出現了與我讀過的有關asm/cglib的奇怪錯誤。任何人都知道我能如何解決這個問題?DebuggingClassWriter覆蓋最終方法訪問

測試先進的搜索動作返回結果

java.lang.NoClassDefFoundError: Could not initialize class org.spockframework.mock.runtime.ProxyBasedMockFactory$CglibMockFactory$ConstructorFriendlyEnhancer 
    at org.spockframework.mock.runtime.ProxyBasedMockFactory$CglibMockFactory.createMock(ProxyBasedMockFactory.java:80) 
    at org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:49) 
    at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:51) 
    at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44) 
    at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:45) 
    at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:281) 
    at org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:83) 
    at uk.ac.xxx.coursefinder.controller.SearchControllerSpec.setup(SearchControllerSpec.groovy:27) 

測試的頁面基本搜索動作返回結果

java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) 
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at net.sf.cglib.core.AbstractClassGenerator.<init>(AbstractClassGenerator.java:38) 
    at net.sf.cglib.core.KeyFactory$Generator.<init>(KeyFactory.java:127) 
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:112) 
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108) 
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104) 
    at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69) 
    at org.spockframework.mock.runtime.ProxyBasedMockFactory$CglibMockFactory.createMock(ProxyBasedMockFactory.java:80) 
    at org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:49) 
    at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:51) 
    at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44) 
    at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:45) 
    at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:281) 
    at org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:83) 
    at uk.ac.xxx.coursefinder.controller.SearchControllerSpec.setup(SearchControllerSpec.groovy:27) 

這裏的網頁是我的測試:

package uk.ac.xxx.coursefinder.controller 

import org.springframework.data.domain.Page 
import org.springframework.data.domain.PageImpl 
import org.springframework.data.domain.PageRequest 
import spock.lang.Specification 
import uk.ac.xxx.coursefinder.command.AdvancedSearchCommand 
import uk.ac.xxx.coursefinder.command.BasicSearchCommand 
import uk.ac.xxx.coursefinder.search.SearchService 
import uk.ac.xxx.coursefinder.solr.domain.CourseGuide 

/** 
* Pure unit test 
*/ 


class SearchControllerSpec extends Specification { 

    SearchController searchController = new SearchController() 

    SearchService searchService 

    def setup() { 
     searchService = Mock() 
     searchController.searchService = searchService 
    } 

    def cleanup() { 
    } 


    def "Test the basic search action returns a page of results"() { 

     given: 
     print "1" 
     Page expectedPage = new PageImpl<CourseGuide>([new CourseGuide()]) 
     BasicSearchCommand basicSearchCommand = new BasicSearchCommand() 
     PageRequest pageRequest = new PageRequest(0, 20) 

     when: "The basic search action is executed with a BasicSearchCommand" 

     Page page = searchController.basic(basicSearchCommand, pageRequest) 

     then: "The correct search service was called with the appropriate arguments and returned expected results" 

     1 * searchService.basic(basicSearchCommand, pageRequest) >> expectedPage 
     page == expectedPage 

    } 

    def "Test the advanced search action returns a page of results"() { 

     given: 
     print "2" 
     Page expectedPage = new PageImpl<CourseGuide>([new CourseGuide()]) 
     AdvancedSearchCommand advancedSearchCommand = new AdvancedSearchCommand() 
     PageRequest pageRequest = new PageRequest(0, 20) 

     when: "The advanced search action is executed with a AdvancedSearchCommand" 

     Page page = searchController.advanced(advancedSearchCommand, pageRequest) 

     then: "The correct search service was called with the appropriate arguments and returned expected results" 

     1 * searchService.advanced(advancedSearchCommand, pageRequest) >> expectedPage 
     page == expectedPage 

    } 


} 

和我的build.gradle文件:

buildscript { 
    ext { 
     grailsVersion = project.grailsVersion 
    } 
    repositories { 
     mavenLocal() 
     maven { url "https://repo.grails.org/grails/core" } 
    } 
    dependencies { 
     classpath "org.grails:grails-gradle-plugin:$grailsVersion" 
     classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.6.4" 
     classpath "gradle.plugin.com.craigburke.gradle:karma-gradle:1.4.3" 
     classpath "gradle.plugin.com.craigburke.gradle:bower-installer-gradle:2.5.1" 
     classpath "org.grails.plugins:hibernate4:5.0.2" 
     classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0" 
     classpath "org.grails.plugins:views-gradle:1.0.4" 
     classpath "net.saliman:gradle-cobertura-plugin:2.3.1" 
    } 
} 


version "0.1" 
group "coursefinder.grails.angular" 

apply plugin:"eclipse" 
apply plugin:"idea" 
apply plugin:"war" 
apply plugin:"org.grails.grails-web" 
apply plugin:"org.grails.grails-gsp" 
apply plugin:"com.craigburke.karma" 
apply plugin:"com.craigburke.bower-installer" 
apply plugin:"asset-pipeline" 
apply plugin:"org.grails.plugins.views-json" 
apply plugin:"net.saliman.cobertura" 


ext { 
    grailsVersion = project.grailsVersion 
    gradleWrapperVersion = project.gradleWrapperVersion 
} 

repositories { 
    mavenLocal() 
    maven { url "https://repo.grails.org/grails/core" } 
    maven { url "http://maven.restlet.org" } //needed for solr core lib 
} 

dependencyManagement { 
    imports { 
     mavenBom "org.grails:grails-bom:$grailsVersion" 
    } 
    applyMavenExclusions false 
} 

dependencies { 
    assets "com.craigburke.angular:angular-template-asset-pipeline:2.2.6" 
    assets "com.craigburke.angular:angular-annotate-asset-pipeline:2.4.0" 
    assets "com.craigburke:js-closure-wrap-asset-pipeline:1.2.0" 
    compile "org.springframework.boot:spring-boot-starter-logging" 
    compile "org.springframework.boot:spring-boot-autoconfigure" 
    compile "org.grails:grails-core" 
    compile "org.springframework.boot:spring-boot-starter-actuator" 
    compile "org.springframework.boot:spring-boot-starter-tomcat" 
    compile "org.grails:grails-plugin-url-mappings" 
    compile "org.grails:grails-plugin-rest" 
    compile "org.grails:grails-plugin-codecs" 
    compile "org.grails:grails-plugin-interceptors" 
    compile "org.grails:grails-plugin-services" 
    compile "org.grails:grails-plugin-datasource" 
    compile "org.grails:grails-plugin-databinding" 
    compile "org.grails:grails-plugin-async" 
    compile "org.grails:grails-web-boot" 
    compile "org.grails:grails-logging" 
    compile "org.grails.plugins:cache" 
    compile "org.grails:grails-plugin-gsp" 
    compile "org.grails.plugins:hibernate4" 
    compile "org.hibernate:hibernate-ehcache" 
    compile "org.grails.plugins:views-json" 
    console "org.grails:grails-console" 

    //solr and rest stuff 
    compile('org.springframework.boot:spring-boot-starter-data-rest') 
    compile('org.springframework.boot:spring-boot-starter-data-solr') 

    //for embedded server 
    compile ('org.apache.solr:solr-core:4.10.4') { 
     exclude(group: "org.slf4j", module: "slf4j-jdk14") 
     exclude(group: "ch.qos.logback", module: "logback-classic") 
    } 

    compile "org.grails.plugins:grails3-cas-client:3.0" 
    compile "org.ccil.cowan.tagsoup:tagsoup:1.2" 


    profile "org.grails.profiles:angular:3.1.3" 
    runtime "com.h2database:h2" 
    runtime "org.grails.plugins:asset-pipeline" 


    testCompile "org.grails:grails-plugin-testing" 
    //testCompile "org.grails.plugins:geb" 
    testCompile "org.grails:grails-datastore-rest-client" 
    //testCompile 'org.mockito:mockito-all:1.10.19' 

    //testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.47.1" 
    //testRuntime "net.sourceforge.htmlunit:htmlunit:2.18" 


    runtime 'org.grails.plugins:grails-console:2.0.4' 

    //testRuntime "org.slf4j:slf4j-api:1.7.10" //stop cobertura class not found exception 


} 

task wrapper(type: Wrapper) { 
    gradleVersion = gradleWrapperVersion 
} 
bower { 
    'angular'('1.4.x') { 
     source 'angular.js' 
    } 
    'angular-resource'('1.4.x') { 
     source 'angular-resource.js' >> '/angular/' 
    } 
    'angular-route'('1.4.x') { 
     source 'angular-route.js' >> '/angular/' 
    } 
    'angular-mocks'('1.4.x') { 
     source 'angular-mocks.js' >> '/angular/' 
    } 
    'angular-bootstrap'('1.1.x') { 
     source 'ui-bootstrap-tpls.js' >> '/angular/' 
    } 
    'bootstrap'('3.x.x') { 
     source 'dist/css/bootstrap.css' >> '/bootstrap/' 
    } 
} 

karma { 
    dependencies(['karma-wrap-preprocessor']) 

    profile 'angularJS' 

    preprocessors = [ 
     'grails-app/assets/javascripts/**/*.js': ['wrap'] 
    ] 

    wrapPreprocessor = [ 
     template: "(function() { 'use strict'; <%= contents %> })()" 
    ] 
} 

assets { 
    minifyJs = true 
    minifyCss = true 
} 

回答

1

我剛剛有一個類似的問題。

似乎cglib:cglib-nodep:2.2.2 lib需要在編譯時可用。它被插入org.grails:grails-plugin-testing插件。

我能用兩種方法解決它;既涉及dependencies {...}build.gradle

1)添加compile 'cglib:cglib-nodep:2.2.2'

或者

2)改變testCompile "org.grails:grails-plugin-testing"compile "org.grails:grails-plugin-testing"

希望它能幫助。