2017-01-07 8 views
0

Spockでgrailsユニットテストを行う場合、サービスインスタンスをドメインに自動挿入できません。Grails Spockでテストするときにドメインにサービスを注入できません

以下は私のコードです。

サービス:

class HiService { 
 

 
    public HiService(){ 
 
     println "Init HiService," + this.toString() 
 
    } 
 

 
    def sayHi(String name){ 
 
     println "Hi, ${name}" 
 
    } 
 
}

ドメイン:

class User { 
 

 
    public User(){ 
 
     if (hiService == null){ 
 
      println "hiService is null when new User(${name})" 
 
     } 
 
    } 
 

 
    String name 
 

 
    def hiService 
 

 
    def sayHi(){ 
 
     println "Before use hiService " + hiService?.toString() 
 
     hiService.sayHi(name) 
 
     println "End use hiService" + hiService?.toString() 
 
    } 
 
}

のTestCase:

@TestFor(HiService) 
 
@Mock([User]) 
 
class HiServiceTest extends Specification { 
 

 
    def "test sayHi"() { 
 

 
     given: 
 
     def item = new User(name: "kitty").save(validate: false) 
 

 
     when: "Use service method" 
 
     item.sayHi() 
 

 
     then : "expect something happen" 
 
     assertEquals(1, 1) 
 
    } 
 
}

以下は、コンソールログました:

--Output from test sayHi-- 
 
Init HiService,[email protected] 
 
hiService is null when new User(null) 
 
Before use hiService null 
 
| Failure: test sayHi(test.HiServiceTest) 
 
| java.lang.NullPointerException: Cannot invoke method sayHi() on null object 
 
\t at test.User.sayHi(User.groovy:17) 
 
\t at test.HiServiceTest.test sayHi(HiServiceTest.groovy:20)

サービスが初期化されますが、ドメインに注入することはできません。しかし、アプリケーションを直接実行すると、サービスはドメインに自動注入されます

+0

あなたは'与えられた中で 'item.hiService = service'を必要とする仕様を拡張します。 – dmahapatro

+1

@dmahapatroそれは働いています、ありがとう – cyj

+0

@dmahapatroドメインの手動での初期化サービスは、各ドメインが複数のサービスを使用する可能性があり、単体テストを行うときに非常に便利ではない、我々は各ユニットテストでマルチドメインを使用する可能性がありますこの問題を解決します? – cyj

答えて

0

autowiringが必要ない場合は、統合テストが必要です。 Grails 3を使用している場合は、@Integrationで注釈を付けます。もしGrails 2がIntegrationSpecを拡張するならば。

を参照してください:あなたはユニットテストを書いているのでhttp://docs.grails.org/latest/guide/testing.html#integrationTesting

0

@Mock([User, HiService]) 
 
class HiServiceTest extends Specification { 
 

 
    def "test sayHi"() { 
 
     // .... 
 
    } 
 
}

0

、あなたのサービスがautowiredされることはありません。また、Userクラスオブジェクトをユニットテストするときは、UserSpec(UserServceTestではなくSuffixing SpecはSpockの規約)でテストを記述する必要があります。今、あなたの代わりにこのようHiServiceを模擬することができます: `ブロック:

クラスUserSpec {

def "User is able to say hi"() { 
    given: 
    User user = new User(name: 'bla bla') 

    and: "Mock the user service" 
    def hiService = Mock(HiService) 
    user.hiService = hiService 

    when: 
    user.sayHi() 

    then: 
    1 * sayHiService.sayHi(user.name) 
} 

}

関連する問題