2016-09-28 81 views
0

我試圖嘲弄newInstance()call()在groovy.sql.Sql:使用mockFor在常規單元嘲笑Sql.call()測試

package com.sample 

import grails.test.GrailsUnitTestCase 
import groovy.mock.interceptor.MockFor 
import groovy.sql.Sql 

class MySampleTests extends GrailsUnitTestCase { 

    void testThat_SqlCall_IsInvokedWithexpectedQuery() { 
     def mockSql = new MockFor(Sql.class) 

     mockSql.demand.newInstance { def datasource-> 
      return mockSql 
     } 

     mockSql.demand.call { def sql -> 
      return 0 
     } 

     mockSql.use { 
      MySample targetObject = new MySample() 
      targetObject.myMethod() 
     } 
    } 
} 

如果這是目標代碼:

package com.sample 

import groovy.sql.Sql 

class MySample { 
    def dataSource 

    def myMethod() { 
    def conn = Sql.newInstance(dataSource) 
    conn.call("test") 
    } 
} 

它犯錯了有:

groovy.lang.MissingMethodException: No signature of method: groovy.mock.interceptor.MockFor.call() is applicable for argument types: (java.lang.String) values: [test] 

的錯誤會使得它看起來像()的調用方法不被嘲笑。是這樣嗎?它是什麼修復?

+1

我覺得最相關的數據缺失這裏有:(A)什麼單元測試框架您使用的? (B)你在使用什麼模擬庫?之後我可能會有更多的問題,但我們從這裏開始。 – BalRog

+0

@BalRog - 我使用mockFor來做嘲弄。根據文檔,它不需要額外的模擬庫。讓我知道如果情況並非如此。就單元測試框架而言,我不確定這個問題的重要性,因爲這個例子沒有任何驗證代碼出現就失敗了。 –

+0

不,我希望你在所有方面都是正確的。這顯然是我不熟悉的Groovy API的許多部分之一。 – BalRog

回答

0

mockSql.metaClass.call更換mockSql.demand.call提供了一個模擬的方法,但需要人工驗證,該方法被調用,參數值:

package com.sample 

import grails.test.GrailsUnitTestCase 
import groovy.mock.interceptor.MockFor 
import groovy.sql.Sql 

class MySampleTests extends GrailsUnitTestCase { 

    void testThat_SqlCall_IsInvokedWithexpectedQuery() { 
     def mockSql = new MockFor(Sql.class) 
     def callInvoked = 0 

     mockSql.demand.newInstance { def datasource-> 
      return mockSql 
     } 

     mockSql.metaClass.call { def sql -> 
      assert sql == "test" 
      ++callInvoked 
      return 0 
     } 

     mockSql.use { 
      MySample targetObject = new MySample() 
      targetObject.myMethod() 
     } 

     assert callInvoked == 1 
    } 
} 

我不知道夠不夠時髦還沒弄清楚爲什麼是這樣的案件,但它解決了我的問題。

其他化妝品的變化加上移動targetObject實例出來的mySql.use {}結果:

package com.sample 

import grails.test.GrailsUnitTestCase 
import groovy.mock.interceptor.MockFor 
import groovy.sql.Sql 

class MySampleTests extends GrailsUnitTestCase { 

    MySample targetObject = new MySample() 

    void testThat_SqlCall_IsInvokedWithexpectedQuery() { 
     def mockSql = new MockFor(Sql) 
     def callInvoked = 0 

     mockSql.demand.newInstance { datasource-> 
      mockSql 
     } 

     mockSql.metaClass.call { sql -> 
      assert sql == "test" 
      ++callInvoked 
      0 
     } 

     mockSql.use { 
      targetObject.myMethod() 
     } 

     assert callInvoked == 1 
    } 
}