Как можно смоделировать часть службы Spring Boot для ВСЕХ моих тестов интеграции Spock? - PullRequest
0 голосов
/ 31 мая 2019

Я использую Spock для создания интеграционных тестов для моего Spring Boot Application, но мне сложно понять, как макетировать часть Сервиса для всех моих тестов.

Мое приложение выполняет запись в базу данных Azure Cosmos, работающую в режиме Gremlin Graph, и, поскольку я не знаю каких-либо баз данных в памяти, чтобы адекватно имитировать ее, я хотел бы убедиться, что любой сервис, который записывает только в мою базу данных разработки взаимодействует с объектами, помеченными случайным UUID текущего теста. Поэтому любой сервис, который читает / пишет в базу данных, должен обязательно включать текущий идентификатор теста в любой запрос.

Как лучше всего смоделировать пару повторно используемых методов в абстрактном базовом классе через Спока?

GraphService.groovy <== Абстрактный класс с некоторыми методами, которые я хочу издеваться. </p>

abstract class GraphService {
    @Autowired 
    protected GraphTraversalSource g

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

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

Несколько служб поиска / изменения базы данных наследуют вышеуказанный класс. Для всех моих тестов вместо g.V() я хочу g.V().has("testID", testId) и вместо g.addV(label) я хочу g.addV(label).property("testID", testId). Как я могу выполнить это во всех моих интеграционных тестах? Я попытался создать класс базовой спецификации, который определил это поведение, но он не работал.

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 ...

1 Ответ

0 голосов
/ 03 июня 2019

Если вам подходит обновление до Spock 1.2, я предлагаю исключить класс TestConfig и использовать аннотацию @SpringBean.

Это пример того, как я настроил его в моих тестах:

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

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

//    ... other stuff
}
...