복붙노트

[SPRING] 사양 클래스 외부에서 Spock 모의 객체를 만드는 방법은 무엇입니까?

SPRING

사양 클래스 외부에서 Spock 모의 객체를 만드는 방법은 무엇입니까?

Spock 테스트와 Spring의 @ContextConfiguration을 결합하여 Spring 컨텍스트에서 Bean을 빌드 한 다음 Spock을 실제 테스트에 사용할 수 있습니다. 우리는 스프링 콩에 스팍 가짜를 주입하고 싶습니다. Mockito에게는 다음과 같은 일을 할 수있는 확장 기능이 있습니다.

 <mockito:mock id="accountService" class="org.kubek2k.account.DefaultAccountService" />

그런 다음이 조롱을 다른 봄 콩으로 참조하십시오. Spock에게는 그러한 확장이 없다. 스펙 클래스 밖에서 Mock을 생성하는 방법을 알고 있다면 다시 빌드하는 것이 너무 많은 노력이 아닐 것이다. 내가 아는 Spock 모의를 만드는 유일한 방법은 다음과 같습니다.

T Mock(Class<T> type)   

사양에. Spring에서 Spock에 Spock mock을 생성 할 수 있도록 Specification 클래스 안에 있지 않을 때 Mock을 만드는 API가 있습니까?

해결법

  1. ==============================

    1.spec 클래스 외부에서 mock을 작성하는 것은 (다른 스펙 클래스에서 사용하는 것) 현재 불가능합니다. 이에 대한 공개 기능 요청이 있습니다. 이것을 구현하는 것이 너무 어렵지는 않지만, 스팍 코어에 약간의 변경이 필요합니다. 적어도 모의 객체를 다른 spec 인스턴스에 수동으로 부착하는 방법이 필요합니다. 아마도 사용자 지향 모의 생성 API를 MockingApi 기본 클래스 밖으로 옮기는 것도 의미가 있습니다.

    spec 클래스 외부에서 mock을 작성하는 것은 (다른 스펙 클래스에서 사용하는 것) 현재 불가능합니다. 이에 대한 공개 기능 요청이 있습니다. 이것을 구현하는 것이 너무 어렵지는 않지만, 스팍 코어에 약간의 변경이 필요합니다. 적어도 모의 객체를 다른 spec 인스턴스에 수동으로 부착하는 방법이 필요합니다. 아마도 사용자 지향 모의 생성 API를 MockingApi 기본 클래스 밖으로 옮기는 것도 의미가 있습니다.

    Nockito를 Spock과 함께 사용할 수 있어야합니다. Spock이 true를 반환하는 도우미 메서드를 호출하여 then-block에 포함 된 모든 확인 코드를 래핑하는 한 Spock은이를 어설 션으로 간주합니다. 다음과 같은 : mockito {/ * mockito 검증은 여기에 있습니다 * /}.

  2. ==============================

    2.Spring 애플리케이션에서 Spock 모의 객체를 사용하는 간단한 해결책을 찾았습니다. 여기에 스프링 기본 구성을위한 mock을 사용하기위한 스프링 구성이 있습니다.

    Spring 애플리케이션에서 Spock 모의 객체를 사용하는 간단한 해결책을 찾았습니다. 여기에 스프링 기본 구성을위한 mock을 사용하기위한 스프링 구성이 있습니다.

    @Configuration @Profile("mocking")
    class MockingContext {
      @Bean Basar basar(){ new DelegatingBasar() }
    }
    
    class DelegatingBasar implements Basar {
      @Delegate Basar delegate
    }
    

    그리고 여기 모의 객체를 생성하고 사용하는 간단한 Spock 사양 :

    @Autowired
    Basar basar
    Basar basarMock
    
    def setup() {
        basarMock = Mock(Basar)
        basar.delegate = basarMock;
    }
    
    def "create a new seller"(User seller) {
        given:
            basarMock.findAllUsers() >> []
        when:
            go "/static/sellers.html"
            waitFor { $("#newUser") }
            $("#newUser").click()
            waitFor { $("#basarNumber") }
            $("#basarNumber").value(seller.basarNumber)
            $("#name").value(seller.name)
            $("#lastname").value(seller.lastname)
            $("#email").value(seller.email)
            $("#saveUser").click()
            waitFor { $("#successfullCreated") }
        then:
            1 * basarMock.saveUser({ newUser ->  
                newUser.basarNumber == seller.basarNumber
                newUser.name        == seller.name
                newUser.lastname    == seller.lastname
                newUser.email       == seller.email
            })
        where:
            seller << [ new User(basarNumber: "100", name: "Christian", lastname: "", email: ""),
                        new User(basarNumber: "ABC", name: "",          lastname: "", email: "")]
    }
    
  3. ==============================

    3.Spock 1.1부터 DetachedMockFactory 및 SpockMockFactoryBean을 사용하면 사양 클래스 외부에서 모의 ​​객체를 만들 수 있습니다. XML 기반 구성을위한 spock 네임 스페이스도 지원됩니다. 설명서에서 사용 예제를 찾을 수 있습니다.

    Spock 1.1부터 DetachedMockFactory 및 SpockMockFactoryBean을 사용하면 사양 클래스 외부에서 모의 ​​객체를 만들 수 있습니다. XML 기반 구성을위한 spock 네임 스페이스도 지원됩니다. 설명서에서 사용 예제를 찾을 수 있습니다.

    Java 기반의 설정과 DetachedMockFactory를 사용한 Spring 테스트는 다음과 같습니다 :

    @ContextConfiguration(classes = [TestConfig, DiceConfig])
    class DiceSpec extends Specification {
        @Autowired
        private RandomNumberGenerator randomNumberGenerator
    
        @Subject
        @Autowired
        private Dice dice
    
        def "uses the random number generator to generate results"() {
            when:
                dice.roll()
    
            then:
                1 * randomNumberGenerator.randomInt(6)
        }
    
        static class TestConfig {
            private final mockFactory = new DetachedMockFactory()
    
            @Bean
            RandomNumberGenerator randomNumberGenerator() {
                mockFactory.Mock(RandomNumberGenerator)
            }
        }
    }
    
    @Configuration
    class DiceConfig {
        @Bean
        Dice dice(RandomNumberGenerator randomNumberGenerator) {
            new Dice(randomNumberGenerator)
        }
    }
    

    XML 기반 구성은 다음과 같습니다.

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:spock="http://www.spockframework.org/spring"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.spockframework.org/spring http://www.spockframework.org/spring/spock.xsd">
        <spock:mock id="randomNumberGenerator" class="RandomNumberGenerator"/>
    </beans>
    

    스팍 스프링 의존성을 포함시켜야합니다.

    testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4-rc-3'
    
  4. ==============================

    4.이것은 "순수한 봄"으로 꽤 똑바로 전달됩니다.

    이것은 "순수한 봄"으로 꽤 똑바로 전달됩니다.

    def parentAppCtx = new StaticApplicationContext()
    parentAppCtx.beanFactory.registerSingleton("myBean", Mock(MyClass))
    parentAppCtx.refresh()
    def appCtx = new ClassPathXmlApplicationContext("spring-config.xml", parentAppCtx)
    

    물론 여러분은 Spring 설정을 적절히 분해하고 있다고 가정한다. (예 : spring-config.xml에서 "myBean"을 재정의하면 ApplicationContext는 본질적으로 Map이며 가장 최근의 정의가 이기기 때문에 spring-config.xml의 정의가 사용됩니다.)

  5. from https://stackoverflow.com/questions/16810646/how-to-create-spock-mocks-outside-of-a-specification-class by cc-by-sa and MIT license