我如何为所有 Spock 集成测试模拟 Spring 引导服务的一部分?

How can I mock part of a Spring Boot service for ALL of my Spock Integration tests?

我正在使用 Spock 为我的 Spring 引导应用程序创建集成测试,但我无法弄清楚如何为 all 模拟服务的一部分我的测试用例。

我的应用程序以 Gremlin Graph 模式写入 Azure Cosmos 数据库 运行,并且由于我不知道有任何内存数据库可以充分模拟它,所以我想确保任何服务写入我的开发数据库只与标有当前测试的随机 UUID 的实体交互。因此 reads/writes 到数据库的任何服务都需要确保在任何查询中包含当前测试 ID。

通过 Spock 在抽象基础 class 中模拟几个重用方法的最佳方法是什么?

GraphService.groovy <== 摘要 class 有一些我想模拟的方法。

abstract class GraphService {
    @Autowired 
    protected GraphTraversalSource g

    protected GraphTraversal buildBaseQuery() {
        return g.V()
    } 

    protected GraphTraversal buildBaseCreationQuery(String label) {
        return g.addV(label)
    }
}

几个数据库 searching/modifying 服务继承了上述 class。对于我所有的测试,我想要 g.V().has("testID", testId) 而不是 g.V() 而不是 g.addV(label) 我想要 g.addV(label).property("testID", testId)。我怎样才能在我所有的集成测试中完成这个?我尝试创建一个基本规范 class 来指定此行为,但没有成功。

TestConfig.groovy

@Configuration
class TestConfig {
    @Bean
    @Primary
    GraphPersistenceService persistenceService(
            GraphTraversalSource g) {
        DetachedMockFactory mockFactory = new DetachedMockFactory()
        GraphPersistenceService persistenceService = mockFactory.Stub( //Mock doesn't work either
            [constructorArgs: [g]], GraphPersistenceService)
        return graphPersistenceService
    }
}

BaseIntegrationTest.groovy

class BaseIntegrationTest extends Specification {
    @Autowired
    TestUtil testUtil

    @Autowired
    GraphTraversalSource g

    @Autowired
    GraphPersistenceService persistenceService

    def setup() {
        persistenceService.buildBaseQuery >> g.V().has("testID", testUtil.id)
        persistenceService.buildBaseCreationQuery(_ as String) >> { label ->
            g.addV(label).property("testID", testUtil.id)
        }
    }

    def cleanup() {
        testUtil.removeAllEntitiesWithCurrentTestId()
    }
}

然后在实际测试中:

@SpringBootTest(classes = MyGraphApplication.class)
@ContextConfiguration(classes = [GraphDbConfig.class, TestConfig.class])
@ActiveProfiles("test")
@TestPropertySource(locations = 'classpath:application-local.properties')
class UserOfPersistenceServiceSpec extends BaseIntegrationTest {
    @Autowired
    UserOfGraphPersistenceService userOfPersistenceService

    def "Can create a bunch of vertices"() {
        expect:
        userOfPersistenceService.createABunchOfVertices() == 5
    }
}

PS。我正在使用 Spring 1.5.10.RELEASE 和 groovy 2.4.15...

如果您可以选择升级到 Spock 1.2,我建议放弃 TestConfig class 并使用 @SpringBean 注释。

这是我在测试中如何设置它的示例:

@ActiveProfiles(["integrationtest"])
@DirtiesContext
abstract class IntegrationTest extends Specification {

    @SpringBean
    EurekaClient eurekaClient = Mock() {
        getNextServerFromEureka(*_) >> Mock(InstanceInfo) {
            getHomePageUrl() >> "test.test"
        }
    }

//    ... other stuff
}