Grails单元测试模拟服务与分配服务实例

时间:2014-12-23 07:36:35

标签: unit-testing grails code-coverage grails-services

模拟服务和将类的实例分配给服务有什么区别?

例如:

class MyService {

   def CallServiceMethod(){
     my business logic
   }
}

class MyController {
   def myService

   def callServiceMethod(){
     myService.callServiceMethod()
   }
}


@TestFor(MyController)
class MyControllerTests {

    @Before
    void setup() {
         controller?.myService = new MyService()
                    vs
         controller?.myService = mockFor(MyService)
    }

    void testCallServiceMethod(){
         controller.callServiceMethod()
    }
}

有人帮我吗?

1 个答案:

答案 0 :(得分:1)

使用Spring时,如果创建一个注册为Spring bean的类的新实例,通常会丢失很多行为。 Bean通常有多个其他bean依赖注入到它们中,并且这些字段在普通新实例中将为null,并且各种注释触发将bean实例包装在一个或多个代理中,这些代理在方法之前和/或之后添加额外的检查和行为。调用 - 并且新实例不会发生这种情况。这些代理包括使用@Transactional获取的事务包装器,来自@Cacheable的缓存检查,以及来自@Secured和其他Spring Security注释的安全检查。

此外,Grails为大多数工件(特别是域类和控制器)添加了大量代码。其中大部分都添加到字节码中,但有些是在运行时添加到元类中。虽然字节码适用于新实例,但在运行时通常需要最后一点配置。例如,有超过100个GORM方法被添加到域类中,但它们不能单独工作,需要“连接”到当前的GORM实现(Hibernate,MongoDB等)。这就是为什么有时会看到错误比如“这个类在Grails应用程序之外使用” - 由于某种原因,该类没有附加GORM impl,因此无法正常运行。

像@TestFor和@Mock这样的mockFor和注释并没有添加所有这些行为,但它们确实添加了它的一大部分,并且它们添加了许多方法的模拟但实际的实现。我们的目标是为您的类的合作者提供足够的类似运行应用程序的行为,使他们的工作方式与在真实应用程序中的工作方式基本相同,这样您就可以专注于正在测试的类,而无需考虑配置测试数据库,或假的网络请求和回复等。