0

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

例如:

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()
    }
}

有人帮帮我吗?

4

1 回答 1

1

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

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

mockFor 和 @TestFor 和 @Mock 之类的注解并没有添加所有这些行为,但它们确实添加了其中的一个很大的子集,并且它们添加了许多方法的模拟但现实的实现。目标是为您的受测班级的协作者提供足够的类似运行应用程序的行为,使他们基本上可以像在真实应用程序中一样工作,因此您可以专注于正在测试的班级,而无需考虑配置测试数据库,或虚假的网络请求和响应等。

于 2014-12-23T08:19:38.640 回答