2011-04-30 65 views
1

我相信這是一個相當常見的情況。我使用Spring Security的核心插件,並希望創建一個具有限於某些角色的一個人域模型:Grails使用Spring Security Core Plugin測試用戶角色自定義驗證約束條件

class Workgroup { 

Person manager 
... 

static constraints = { 
    manager(validator: {mgr -> 
      // it feels like there should be a more elegant, groovy way of doing this. 
      def auths = mgr.getAuthorities(); 
      def returny = false 
      auths.each { 
       if(it.authority == 'ROLE_MANAGER') 
       { 
        returny = true 
       } 
      } 
      return returny 
     }) 
} 

}

測試失敗像美富:

void testInvalidManager() { 
    def nick = new Person(username:'Nick') 
    def nonManagerRole = new Role(authority:'ROLE_EMPLOYEE') 
    UserRole.create(nick,nonManagerRole) 
    def awesome = new Workgroup(name:'mooCows', manager:nick) 
    mockForConstraintsTests(Workgroup, [awesome]) 
    assertFalse awesome.validate() 
    assertEquals "validator", awesome.errors["manager"] 
} 

testInvalidManager錯誤沒有方法的簽名:users.UserRole.save()適用於參數類型:(java.util.LinkedHashMap)值:[[flush:false,insert:true]]可能的解決方案:wait(),any ),wait(long),use([Ljava.lang.Object;),isCase(java.lang.Object),each(groovy.lang.Closure)

groovy.lang.MissingMethodException:沒有方法簽名:users.UserRole.save()適用於參數類型:(java.util.LinkedHashMap)values:[[flush:false,insert:true]] 可能解決方案:在users.UserRole.create上使用wait(),any(),wait(long),use([Ljava.lang.Object;),isCase(java.lang.Object),each(groovy.lang.Closure) (UserRole.groovy:32) 在users.UserRole.create(UserRole.groovy) 在users.UserRole $ create.call(未知來源) 在users.WorkgroupTests.testInvalidManager(WorkgroupTests.groovy:17)

集成比單元測試更好地涵蓋了這一點嗎?我是否需要模擬UserRole(如果有,如何?)?這些類型的測試通常如何進行?

回答

2

UserRole.create()來電save(),所以你需要使用mockDomain()而不是隻有mockForConstraintsTests()

但是,只有當你用模擬測試領域模型時,我纔不會這麼做。在測試控制器或其他使用域類的類時,應該使用Grails中的模擬支持,但不應該對真正的持久性,創建數據庫(甚至是內存中)等等感到困擾。通過消除您關注的依賴關係當前層,相信其他層已經正確測試。但是當你使用模擬來測試域類時,你實際上只是在測試模擬框架。所以我總是使用域類的集成測試,以便它們針對真實的數據庫運行。

爲了回答您的代碼示例中的隱性問題,我會寫約束爲

static constraints = { 
    manager validator: { mgr -> 
     mgr.authorities.find { it.authority == 'ROLE_MANAGER' } != null 
    } 
} 

其體積的問題是,你使用的每一個()當一個普通的for循環將是可取的因爲你可以從for循環返回。只有當你真的想在每個實例上調用閉包時才使用each()。這裏有一個比其他少了一個時髦,但使用for循環:

static constraints = { 
    manager validator: { mgr -> 
     for (auth in mgr.getAuthorities()) { 
     if (it.authority == 'ROLE_MANAGER') { 
      return true 
     } 
     } 
     return false 
    } 
} 
+0

這必須是另一個問題或Grails的用戶討論的話題,但你爲什麼不測試領域類加入了'mockDomain()' ?例如,我的域邏輯包括幾個'findBy *()',而不是'parent.children.find {}' - 爲什麼它可能不好? 我對你的意見非常感興趣,因爲我知道你在Grails中的角色。 – 2011-05-01 06:30:40

+0

您應該使用mockForConstraintsTests測試域類,以驗證您的域約束。否則,您使用mockDomain提供域對象,這些域對象的行爲與正確的域對象相同,因此可以針對它們測試服務和控制器。 – 2011-05-01 17:35:33

相關問題