关于java:如何使用Spock 测试Grails 服务?

How to test Grails service using Spock?

我有一个带有以下方法的 EncouragementService.groovy

1
2
3
4
5
6
7
8
9
10
11
12
13
  class EncouragementService {
   def stripePaymentService

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

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

如何在 grails 中实现同样的功能,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

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

服务类可以优化如下:

1
2
3
4
5
6
7
8
9
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)。测试类看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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>
  }
}


使用 build-test-data 插件构建用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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\\ 的关键字。