从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')
}