【问题标题】:How to test Grails service using Spock?如何使用 Spock 测试 Grails 服务?
【发布时间】:2013-09-09 18:36:11
【问题描述】:

我有一个EncouragementService.groovy,方法如下

  class EncouragementService {
   def stripePaymentService 

   def encourageUsers(List<User> users){
     if(null != users && users.size()>0){
      for(User user : users){
        //logic
        stripePaymentService.encourage(user)
        //
      }
     }   
   }
  }

要在 JAVA 世界中测试上面的代码,我会首先使用 JUnit 在 setup 中创建两个或三个用户。将用户列表传递给encourageUsers(...) 方法并检查我想要的结果。

如何在 grails 中实现同样的目标,

import com.github.jmkgreen.morphia.Datastore;

@TestFor(EncouragementService)
class EncouragementServiceSpec {

  def morphiaService = new MorphiaService()

  void testEncourageUsers() {
        List<User> users = createUsers();
        encouragementService.(users)  
            //
  }

  def createUsers(){
       Datastore datastore = morphiaService.dataStoreInstance()
       def user = new User()
       user.setName("Prayag Upd")
       //
       datastore.save(user)
       [user]
  }
}

我正在使用spock:0.7

plugins {
    test(":spock:0.7") { exclude "spock-grails-support" }
}

【问题讨论】:

    标签: java unit-testing grails groovy spock


    【解决方案1】:

    服务类可以优化如下:

    class EncouragementService {
       def encourageUsers(List<User> users){
           if(users){ //Groovy truth takes care of all the checks
              for(user in users){
                //logic
              }
           }   
       }
    }
    

    Spock 单元测试:
    Spock 将测试提升到另一个层次,您可以在其中测试行为(遵守 BDD)。测试类看起来像:

    import spock.lang.*
    
    @TestFor(EncouragementService)
    @Mock(User) //If you are accessing User domain object.
    class EncouragementServiceSpec extends Specification{
      //def encouragementService //DO NOT NEED: mocked in @TestFor annotation
    
      void "test Encourage Users are properly handled"() {
          given: "List of Users"
              List<User> users = createUsers()
    
          when: "service is called"
              //"service" represents the grails service you are testing for
              service.encourageUsers(users) 
    
          then: "Expect something to happen"
              //Assertion goes here
      }
    
      private def createUsers(){
           return users //List<User>
      }
    }
    

    【讨论】:

    • “耐心”是my name,我不是在开玩笑;)。坦率地说,最近我在本地 Grails 用户组的 spock 上有一个 presentation,所以我想我会吹嘘我所做的一些事情。 ;) @SérgioMichels
    • @dmahapatro 当User 不是基于grails-app/domain 的实体时,我得到Failure: test Users are properly handled(np.zazzercode.service.EncouragementServiceSpec) | org.codehaus.groovy.grails.exceptions.GrailsConfigurationException: Cannot add Domain class [class np.zazzercode.domain.User]. It is not a Domain! at grails.test.mixin.domain.DomainClassUnitTestMixin.registerGrailsDomainClass(DomainClassUnitTestMixin.groovy:209)
    • @PrayagUpd 是的,如果 User 不是域类,那么您将不需要 @Mock 这就是我在答案中的意思。
    • @dmahapatro 好的,但是我如何初始化在EncouragementService 中使用的服务(例如stripePaymentService)。由于没有注入,因此在测试应用程序时抛出 java.lang.NullPointerException: Cannot invoke method encourage() on null object
    • @dmahapatro 好吧,将def stripePaymentService = Mock(StripePaymentService) service.stripePaymentService = stripePaymentService 添加到given 已修复
    【解决方案2】:

    使用build-test-data plugin 建立用户。

    @TestFor(EncouragementService)
    @Build(User)
    class EncouragementServiceSpec extends Specification {
    
      def "encourage users does x"() {
        given:
        def users = createUsers();
    
        when:
        service.encourageUsers(users)  
    
        then:
        // assert something
      }
    
      def createUsers(){
        [User.build(), User.build(), User.build()]
      }
    }
    

    我还对代码进行了一些更改,以使其成为正确的 spock 规范。您的测试必须扩展规范,您可能想熟悉Spock's keywords

    【讨论】:

    • build-test-data plugin 看起来很棒,但似乎不适用于非基于grails-app/domain 的实体。抛出异常org.codehaus.groovy.grails.exceptions.GrailsConfigurationException: Cannot add Domain class [class np.zazzercode.domain.User]. It is not a Domain
    猜你喜欢
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 2015-01-07
    • 2016-06-07
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多