2015-10-19 58 views
0

我正嘗試使用G-Func框架爲我們的基於Grails的REST API編寫自動功能測試。在Grails中引導休眠G-Func功能測試

我對GET測試沒有任何問題。但是,POST測試提出了一個嚴重的挑戰,我無法解決。問題是發佈請求後,我需要驗證數據庫已被適當修改,並且我想使用GORM來完成。

(代碼和輸出下面僅包含凸片段)

取1:

package com.mycompany.api 

import com.grailsrocks.functionaltest.* 

class MyDomainObjectFunctionalTests extends APITestCase { 

    void test1() { 
    println MyDomainObject.count() 
    .... 

運行它以:

grails test-app functional: com.mycompany.api.MyDomainObjectFunctional -echoOut 

輸出:

| Failure: test1(com.mycompany.api.MyDomainObjectFunctionalTests) 
| java.lang.IllegalStateException: Method on class [com.mycompany.data.MyDomainObject] 
was used outside of a Grails application. If running in the context of 
a test using the mocking API or bootstrap Grails correctly. 

以2:

package com.mycompany.api 

import com.grailsrocks.functionaltest.* 

class MyDomainObjectFunctionalTests extends APITestCase { 

    void test1() { 

    HibernateDatastoreSpringInitializer init = new HibernateDatastoreSpringInitializer("com.mycompany.data") 
    // com.mycompany.data is the package where the domain objects live 

    init.configuration.setProperty("hibernate.hbm2ddl.auto", 'none') 
    init.configuration.setProperty("hibernate.show_sql", 'true') 
    init.configuration.setProperty("hibernate.default_schema", 'myschema') 

    def dataSource = new DriverManagerDataSource(myDbUrl) 
    dataSource.setDriverClassName("com.mysql.jdbc.Driver") 

    init.configureForDataSource(dataSource) 

    println MyDomainObject.count() 
    .... 

輸出:

Hibernate: select count(*) as y0_ from myschema.my_domain_object this_ 
ERROR 14:49:34:463 util.JDBCExceptionReporter 
Table 'myschema.my_domain_object' doesn't exist 

表名是不正確的:它應該是myDomainObject,不my_domain_object - 我們正在使用自定義Hibernate的命名策略。

(順便說一句,數據庫連接是好的:如果我使用數據源連接對象,並針對myDomainObject表它的工作原理寫一本手冊SQL查詢)。

所以現在我嘗試通過自定義命名策略休眠:

以3:

package com.mycompany.api 

import com.grailsrocks.functionaltest.* 

class MyDomainObjectFunctionalTests extends APITestCase { 

    void test1() { 

    HibernateDatastoreSpringInitializer init = new HibernateDatastoreSpringInitializer("com.mycompany.data") 

    init.configuration.setProperty("hibernate.hbm2ddl.auto", 'none') 
    init.configuration.setProperty("hibernate.show_sql", 'true') 
    init.configuration.setProperty("hibernate.default_schema", 'myschema') 

    init.configuration.setProperty("hibernate.naming_strategy", 'com.mycompany.data.OurNamingStrategy') 

    def dataSource = new DriverManagerDataSource(myDbUrl) 
    dataSource.setDriverClassName("com.mysql.jdbc.Driver") 

    init.configureForDataSource(dataSource) 

    println MyDomainObject.count() 
    .... 

我也調試添加打印OurNamingStrategy.classToTableName

package com.mycompany.data 

import org.hibernate.cfg.ImprovedNamingStrategy 

class OurNamingStrategy extends ImprovedNamingStrategy { 

    @Override 
    public String classToTableName(String className) { 
    ... 
    println 'Table name for class ' + className + ': ' + tableName; 
    return tableName; 
    } 
    ... 

輸出:

... 
Table name for class MyDomainObject: myDomainObject 
... 

Hibernate: select count(*) as y0_ from myschema.my_domain_object this_ 
ERROR 14:49:34:463 util.JDBCExceptionReporter 
Table 'myschema.my_domain_object' doesn't exist 

因此,看起來Hibernate確實考慮到了自定義命名策略,但是它在發出查詢時會拋棄它。

在這一點上,我卡住了。任何建議如何我可以使這項工作?

的Grails版本2.4.4

+0

我想你可能想要使用https://github.com/alkemist/grails-remote-control/ – cfrick

+0

@cfrick:我看了一下。我不明白它會如何幫助我。我也試過Geb,但是我一直遇到生成足夠強大的HTPP請求的問題(例如,使用自定義請求頭等)grailsrocks至少可以幫助解決後面的問題 –

+0

在運行功能測試時,您基本上在世界的客戶端。所有的服務,gorm,...都不可用。遠程控制可以幫助您在服務器端設置/斷言。但是這當然只會對你有幫助,如果你在你的問題中描述的只是這個問題的症狀/解決方法。我可能誤解了你的問題 – cfrick

回答

0

顯然,這是在HibernateDatastoreSpringInitializer的錯誤。我檢查了代碼,雖然我沒有查明錯誤的確切位置,我能夠拿出一個解決辦法:

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder 

... 

void test1() { 

    // HACK!!! GORM naming strategy workaround 
    GrailsDomainBinder.NAMING_STRATEGIES['DEFAULT'] = new OurNamingStrategy() 

    HibernateDatastoreSpringInitializer init = new HibernateDatastoreSpringInitializer("com.mycompany.data") 
    ... 

看來,由於錯誤格姆搶不正確的命名策略對象(它存儲在GrailsDomainBinder.NAMING_STRATEGIES['dataSource']),而是默認的對象。通過重寫該條目,我可以達到所需的行爲。