如何在Grails 3中填充单元测试中的域类

时间:2016-02-24 11:10:55

标签: unit-testing grails gorm spock grails-3.0

我想知道如何构建一个Domain类对象的世界,以便在我的单元测试中使用。最好的方法是什么?

说这是我的代码,ServiceX:

   List<Course> getAllCoursesByType(String type) {
        List<Course> list = Course.findAllByType(type)
        list
   }

这是对ServiceX的测试:

 import grails.buildtestdata.mixin.Build
 import grails.test.mixin.TestFor
 import grails.test.mixin.Mock
 import spock.lang.Specification


  @TestFor(ServiceX)

    class ServiceXSpec extends Specification { 

      void "get all open courses"() {
       given:
       String type = "open"
       when:
       def list = service.getAllCoursesByType(type)

       then:
      list.size() == 4
     }

}

我如何“预填充”test-db(内存)母猪,我实际上在列表中有4个这样的对象?

3 个答案:

答案 0 :(得分:1)

为此创建集成测试。查看示例here

答案 1 :(得分:0)

这是判断何时使用慢速积分测试进行测试的判断。关键是测试你的代码,而不是Grails / hibernate数据库代码。

大部分服务测试不应该需要集成测试。我认为您需要对运行系统中具有真实数据库的对象交互进行集成测试。我倾向于在使用GEB的GUI测试中这样做。这些测试通常涵盖基本的端到端方案。它测试服务器端和GUI与服务器的交互。

在GUI / GEB测试中,我不测试服务的所有排列和边缘条件。我在单元测试中进行了大部分边缘测试。

我发现使用Grails,如果一个简单的DB动作在集成测试中起作用,那么大多数其他简单的DB动作都可以工作。用于save(),delete()等的Grails域模拟模拟真实的&#39;数据库操作相当不错。 注意:它们对内存中的对象进行操作,因此它们并不完全相同。

我不使用Spock,但是使用JUnit我使用这种方法(仍然适用于Grails 3):

@TestFor(ServiceX)
@Mock([Course])
class ServiceXTests {
}

@Test
void testXYZ() {
  def course= new Course(course: 'ABC')
  assert course.save()
  . . . 
}

这似乎得到了Spock的支持。我认为这个域记录的创建属于Spock&#39;给出的&#39;部分。另请参阅Grails Testing

另一个很好的资源是在Github上搜索Grails来源。我从他们的例子中学到了很多东西。

答案 2 :(得分:0)

事实证明,您可以向域类添加/覆盖方法(例如),如下所示:

import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
import grails.test.mixin.Mock


@Mock([Course])
@TestFor(ServiceX)

class ServiceXSpec extends Specification { 

  void "get all open courses"() {
   given:
   String type = "open"

   Course.metaclass.static.findAllByType = { String type -> [new Course()]}
   when:
   def list = service.getAllCoursesByType(type)

   then:
   list.size() == 1
 }

}