重用spock mock并注入规范

时间:2016-10-10 21:30:52

标签: mocking spock

从Mockito转到Spock。

我想创建一个可重用的 spock 模拟器并将其注入多个测试中。

除了使用测试实例成员,用于模拟和存根的fixture方法之外,我可以注入已经存根的模拟吗?

规范

package com.cpg

import com.cpg.service.FooBarService
import org.spockframework.mock.MockUtil
import org.springframework.beans.factory.annotation.Autowired
import spock.lang.Shared

class InjectableMockSpecification extends BaseSpecification {

    @Shared
    FooBarService injectedMockService

    def "invoke injected mock test"() {
        setup:
            assert injectedMockService != null
            new MockUtil().attachMock(injectedMockService, this)

        when:
            def response = injectedMockService.method("foo")

        then:
            response == "bar"

        cleanup:
            new MockUtil().detachMock(injectedMockService)
    }

    @Autowired
    void setMock(FooBarService mock) {
        this.injectedMockService = mock
    }
}

测试配置

package com.cpg

import com.cpg.service.FooBarService
import org.springframework.boot.test.SpringApplicationConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.test.context.web.WebAppConfiguration
import spock.lang.Specification
import spock.mock.DetachedMockFactory

@SpringApplicationConfiguration(classes = [TestConfig, MockConfig])
@WebAppConfiguration
class BaseSpecification extends Specification {

    @Configuration
    static class MockConfig {
        @Bean
        public FooBarService mock() {
            FooBarService mock = new DetachedMockFactory().Mock(FooBarService, name: "fooBarService")
            //is it posssible to perform stubbing here??
            //injectedMockService.method(_ as String) >> { return "bar" } //valid groovy, just triggers nullpointer on >> operator
            return mock
        }
    }
}

任何建议表示赞赏。

更新:     我注入了一个MockFactory类,可以为我注入并构建存根。

@Service
class UserManagerMockFactory extends Specification {

  UserManager getUserDetailsyByUserIdMock(String mockPath) {
    UserManager mock = Mock()
    UserDetails response = new UserDetails(new JsonSlurper().parse(new ClassPathResource(mockPath).inputStream))
    mock.getUserDetailsyByUserId(*_) >> response
    return mock
  }


   /**
   * Mock for three consecutive invocations.
   */
  UserManager getUsersMock() {
    UserManager manager = Mock()
    manager.getUsers(_) >>> [
        generate(10),        // page one with 10 users
        generate(10),       // page two with 10 users
        generateResponse(0)  // empty page
    manager
  }

  /**
   * Mock for throwable response.
   */
  UserManager getUserDetailsyByUserIdMockThrowingExceptionMock() {
    UserManager mockManager = Mock()
    mockManager.getUserDetailyByUserId(*_) >> { throw new UserNotFoundException() }
    mockManager
  }

}


// inject mock factory into specification class 
@Autowired
private UserManagerMockFactory userManagerMockFactory

// usage in Specification class    
def setup() {
this.testService.userManager = userManagerMockFactory.getUsersMock('mocks/userManager.testUser.json')
}

0 个答案:

没有答案