2016-01-12 67 views
1

我們對非域類進行驗證,該類在運行應用程序時正常工作。但是,我們希望單元測試驗證,但測試似乎忽略了約束塊並僅使用默認驗證約束。如何在非域類上測試Grails驗證

這裏是我們的生產類:

import grails.validation.Validateable 

@Validateable 
class TransactToken { 

    String institutionId 
    String username 
    boolean expired = false 
    //optional fields 
    String email 
    String customCssUrl 
    String roleName = Role.CARDHOLDER 

    static constraints = { 
     institutionId blank: false 
     username blank: false 
     expired notEqual: true 
     email email: true, nullable: true 
     customCssUrl url: true, nullable: true 
     roleName inList: [ Role.DIRECTOR, Role.OFFICE, Role.CARDHOLDER] 
    } 

} 

而我們的測試類:

import spock.lang.Specification 
import spock.lang.Unroll 

class TransactTokenSpec extends Specification { 

    @Unroll 
    void "test isValid (institutionId: #institutionId, username: #username, expired: #expired, roleName: #roleName)"() { 
     given: "A token with the provided params" 
     TransactToken transactToken = new TransactToken(
       institutionId: institutionId, 
       username: username, 
       expired: expired, 
       roleName: roleName, 
       email: "[email protected]", 
       customCssUrl: "http://bacon.edu" 
     ) 

     when: 
     transactToken.validate() 
     if (transactToken.hasErrors()) {println transactToken.errors} 

     then: 
     valid != transactToken.hasErrors() 

     where: 
     institutionId | username | expired | roleName  || valid 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER || true 
     'asdf'  | ''  | false | Role.CARDHOLDER || false 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER || true 
     ''   | 'asdf' | false | Role.CARDHOLDER || false 
     'asdf'  | ''  | false | Role.CARDHOLDER || false 
     'asdf'  | 'asdf' | true | Role.CARDHOLDER || false 
     'asdf'  | 'asdf' | false | Role.OFFICE  || true 
     'asdf'  | 'asdf' | false | Role.DIRECTOR || true 
     'asdf'  | 'asdf' | false | Role.ADMIN  || false 

    } 

} 

回答

2

所以,這是一個黑客位,但我們想通了這一點。

我認爲問題是我們需要@TestFor註解,我似乎沒有爲非grails類工作。

依賴於此類驗證並使用@TestFor註釋的服務,所以我們將此測試移到那裏,並且按預期工作。

@TestFor(TransactTokenService) 
@ConfineMetaClassChanges(Organization) 
class TransactTokenServiceSpec extends Specification { 

    @Unroll 
    void "test #label: valid should be #valid."() { 
     given: "A token with the provided params" 
     TransactToken transactToken = new TransactToken(
       institutionId: institutionId, 
       username: username, 
       expired: expired, 
       roleName: roleName, 
       customCssUrl: url, 
       email: email 
     ) 

     when: 
     transactToken.validate() 

     then: 
     valid != transactToken.hasErrors() 

     where: 
     institutionId | username | expired | roleName  | email    | url     || valid || label 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER | "[email protected]"| "http://sharptop.co" || true || "all valid" 
     'asdf'  | ''  | false | Role.CARDHOLDER | ""     | ""     || false || "blank username" 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER | ""     | ""     || true || "blank email and url" 
     ''   | 'asdf' | false | Role.CARDHOLDER | ""     | ""     || false || "blank institution id" 
     'asdf'  | 'asdf' | true | Role.CARDHOLDER | ""     | ""     || false || "expired token" 
     'asdf'  | 'asdf' | false | Role.OFFICE  | ""     | ""     || true || "valid office user" 
     'asdf'  | 'asdf' | false | Role.DIRECTOR | ""     | ""     || true || "valid director user" 
     'asdf'  | 'asdf' | false | Role.ADMIN  | ""     | ""     || false || "invalid admin user" 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER | "[email protected]"| "bacon"    || false || "invalid url" 
     'asdf'  | 'asdf' | false | Role.CARDHOLDER | "bacon"   | "http://sharptop.co" || false || "invalid email" 
    } 
} 
+1

使用'@TestFor(TransactTokenService)'有點奇怪,因爲測試看起來與服務沒有任何關係。我認爲更好的主意是用'@TestMixin(GrailsUnitTestMixin)'標記測試。我們在http://grails.github.io/grails-doc/3.0.9/guide/testing.html#unitTesting(在該頁面上搜索「MyValidateableSpec」)的用戶指南中包含了一個示例。 –