简体   繁体   English

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

[英]Grails unit test mock service vs assign service instance

What is the difference between mocking service and assign instance of class to service? 模拟服务和将类的实例分配给服务有什么区别?

For example: 例如:

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

Any one help me please? 有人可以帮我吗?

When using Spring, you typically lose a lot of behavior if you create a new instance of a class that's registered as a Spring bean. 使用Spring时,如果创建一个注册为Spring bean的类的新实例,通常会损失很多行为。 Beans often have multiple other beans dependency-injected into them and those fields would be null in a plain new instance, and various annotations trigger wrapping the bean instance in one or more proxies that add extra checks and behavior before and/or after your methods are called - and that won't happen with a new instance. Bean通常具有多个其他依赖注入的Bean,这些字段在一个普通的新实例中将为null,并且各种注释触发将Bean实例包装在一个或多个代理中,从而在您的方法执行之前和/或之后添加额外的检查和行为。称为-不会在新实例中发生。 These proxies include the transactional wrapper you get with @Transactional, the cache checks from @Cacheable, and security checks from @Secured and other Spring Security annotations. 这些代理包括您通过@Transactional获得的事务包装,来自@Cacheable的缓存检查以及来自@Secured和其他Spring Security批注的安全检查。

In addition, Grails adds a lot of code to most artifacts (in particular domain classes and controllers). 另外,Grails向大多数工件(特别是域类和控制器)添加了很多代码。 Most of that is added to the bytecode, but some is added at runtime to the metaclass. 大多数都添加到字节码中,但有些在运行时添加到元类中。 Although the bytecode is there for a new instance, it often needs a final bit of configuration at runtime. 尽管字节码用于新实例,但它通常需要在运行时进行最后的配置。 For example there are over 100 GORM methods added to domain classes, but they don't work by themselves and need to be "hooked up" to the current GORM implementation (Hibernate, MongoDB, etc.) This is why you sometimes see an error like "this class was used outside of a Grails application" - the class for some reason didn't have a GORM impl attached, so it can't function. 例如,有超过100种GORM方法添加到域类中,但是它们本身无法运行,需要“钩住”当前的GORM实现(Hibernate,MongoDB等)。这就是为什么有时会看到错误的原因就像“该类在Grails应用程序外部使用”一样-该类由于某种原因未附加GORM impl,因此无法运行。

mockFor and annotations like @TestFor and @Mock don't add all of this behavior, but they do add a large subset of it, and they add mocked but realistic implementations of many methods. mockFor和@TestFor和@Mock之类的注释并没有添加所有这种行为,但是它们确实添加了它的很大一部分,并且它们添加了许多方法的模拟但现实的实现。 The goal is to give the collaborators of your class under test enough run-app-like behavior that they work essentially like they would in a real app, so you can focus on the class being tested without having to think about configuring a test database, or fake web requests and responses, etc. 目的是让被测类的协作者有足够的类似于运行应用的行为,使其在本质上就像在真实应用中那样工作,因此您可以专注于被测类,而不必考虑配置测试数据库,或虚假的网络请求和响应等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM