Интеграционное тестирование с репозиториями SDN4 с использованием neo4j-пространственных шифровых запросов

Я начинаю использовать neo4j-atial в некоторых моих кодах. Я думал, что смогу провести интеграционный тест пространственного кода neo4j, включив библиотеку пространственного сервера в качестве зависимости maven в моем проекте. Это не сработало для меня, хотя. Я не могу найти никаких документов по этому вопросу.

Как я могу заставить мои интеграционные тесты работать?

Любые советы кто-нибудь?:)

Просто чтобы дать представление о том, что я делаю, я вставил ниже сегмент моего кода контроллера, сервиса и репозитория, а окончательная публикация кода - мои тесты, которые не работают со встроенным TestServer.

вместилище

package nz.co.domain.core.repository.location;

import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import nz.co.domain.model.pojos.Location;

@Repository
public interface LocationRepository extends GraphRepository<Location> {

    @Query("match (n:Location {domainId : {domainId}}) with n call spatial.addNode({layerName}, n) yield node return node;")
    public Location indexLocation(@Param("domainId") String locationId, @Param("layerName") String layerName);

    @Query("call spatial.withinDistance({layerName},{longitude: {longitude},latitude: {latitude}}, {rangeInKms});")
    public Iterable<Location> findLocationsWithinRange(@Param("longitude") String longitude, @Param("latitude") String latitude, @Param("rangeInKms") String rangeInKms, @Param("layerName") String layerName);

    @Query("call spatial.addPointLayer({layerName});")
    public void createLayer(@Param("layerName") String layerName);

    @Query("match ()-[:LAYER]->(n) where n.layer = {layerName} return count(n) > 0;")
    public boolean hasLayer(@Param("layerName") String layerName);

    public Location findByDomainSpecificId(String domainSpecificId);

    public Location findByGooglePlaceId(String googlePlaceId);

}

обслуживание

package nz.co.domain.core.location;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import nz.co.domain.core.repository.location.LocationRepository;
import nz.co.domain.model.UniqueIDGenerator;
import nz.co.domain.model.pojos.Location;

@Service
public class LocationService {

    @Inject
    private LocationRepository locationRepository;

    public void createLayer(String layerName) { 
        locationRepository.createLayer(layerName);
    }

    public Location createLocation(double latitude, double longitude, String googlePlaceId, String layerName) { 
        Location location = new Location(UniqueIDGenerator.randomID(), googlePlaceId, latitude, longitude);
        boolean hasLayer = locationRepository.hasLayer(layerName);
        if (!hasLayer) { 
            locationRepository.createLayer(layerName);
        }

        Location preExistingLocation = locationRepository.findByGooglePlaceId(googlePlaceId);

        if (preExistingLocation == null) { 
            location = locationRepository.save(location);
            location = locationRepository.indexLocation(location.getDomainId(), layerName);
        } else { 
            location = preExistingLocation;
        }

        return location;
    }

    public Iterable<Location> findLocationsWithinRange(String latitude, String longitude, String rangeInKms, String layerName) { 
        return locationRepository.findLocationsWithinRange(longitude, latitude, rangeInKms, layerName);
    }

    public Location loadLocationByGooglePlaceId(String googlePlaceId) {
        return locationRepository.findByGooglePlaceId(googlePlaceId);
    }

    public Location loadLocationByDomainId(String domainId) {
        return locationRepository.findByDomainId(domainId);
    }

}

контроллер

...

/**
     * Add location. 
     * @param profiletypes
     * @param profileId
     * @return
     */
    @RequestMapping(value = "/{profileType}/{profileId}/location", method = RequestMethod.POST, produces = "application/hal+json")
    public HttpEntity<LocationResource> addLocation(@PathVariable String profileType,
            @PathVariable String profileId, @RequestBody CreateLocationRequest locationRequest, @ApiIgnore LocationResourceAssembler locationResourceAssembler) {

        Profile profile = profileService.loadProfileByDomainId(profileId);

        Location location = locationService.createLocation(locationRequest.getLatitude(), locationRequest.getLongitude(), locationRequest.getGooglePlaceId(), profileType + "-layer");

        profile.setLocation(location);
        profileService.save(profile);

        location = locationService.loadLocationByGooglePlaceId(location.getGooglePlaceId());

        LocationResource resource = locationResourceAssembler.toResource(location);
        return new ResponseEntity<>(resource, HttpStatus.CREATED) ;
    }

...

Сервисный тест

(Это мои тесты, которые я не могу использовать как часть стандартной сборки для встроенного TestServer)

package nz.co.domain.core.location;

import javax.inject.Inject;

import org.junit.Ignore;
import org.junit.Test;

import nz.co.domain.core.AbstractTest;
import nz.co.domain.model.pojos.Location;

public class LocationServiceTest extends AbstractTest {

    @Inject
    private LocationService locationService;

    @Test
    public void indexLocationTest() { 

        // The Rogue and Vagabond
        Location rogueAndVagabond = locationService.createLocation(51.469150, 7.23212, "ChIJmwfKGdivOG0R9eTCVFOngnU", "test-layer");

        /* more test code here */

        // Te Papa Museum
        Location tePapaMuseum = locationService.createLocation(-41.289964, 174.778354, "ChIJfxn9AdGvOG0RpLRGGO3tRX8", "test-layer");

        /* more test code here */

        // Porirua Club
        Location poriruaClub = locationService.createLocation(-41.136048, 174.836409, "ChIJ9wl16m1TP20R3G3npuEokak", "test-layer");

        /* more test code here */

        Iterable<Location> findLocationsWithinRange = locationService.findLocationsWithinRange("-41.289964", "longitude", "5", "test-layer");

       /* more test code here */

    }
}

2 ответа

Решение

Пространственная функциональность пока не предоставлена ​​в SDN 4. Если вы интегрируете neo4j-atial lib, то единственный вариант, который у вас есть на данный момент, - это использовать его напрямую - не будет поддержки репозитория и т. Д. Однако в настоящее время работа по пространственной интеграции продолжается, поэтому некоторые основные функции должны быть введены в следующий выпуск

Мы используем SDN 4.1.2, OGM 2.0.3 и мои тесты работают с этой настройкой:

Добавлена ​​зависимость maven с использованием описания на странице github. Ко времени написания этого комментария необходимо добавить pom.xml было

<repositories>
    <repository>
        <id>neo4j-contrib-releases</id>
        <url>https://raw.github.com/neo4j-contrib/m2/master/releases</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>neo4j-contrib-snapshots</id>
        <url>https://raw.github.com/neo4j-contrib/m2/master/snapshots</url>
        <releases>
            <enabled>false</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
<!-- ... -->
<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-spatial</artifactId>
    <version>0.19-neo4j-3.0.3</version>
</dependency>

Определение следующих абстрактных классов для всех пространственных тестов:

@RunWith(SpringJUnit4ClassRunner::class)
@SpringApplicationConfiguration(classes = arrayOf(Application::class))
@ActiveProfiles("test")
@Transactional
abstract class AbstractIntegrationTests() {}

а также

@WebAppConfiguration
abstract class AbstractIntegrationTestsWithProcedures : AbstractIntegrationTests() {

    lateinit var databaseService: GraphDatabaseService
    val layerName = "layer"

    @Before()
    open fun before() {
        if (ProcedureTestUtil.registeredProcedures.contains(SpatialProcedures::class.java)) {
            return
        }
        val driver = Components.driver()
        if (driver is EmbeddedDriver) {
            databaseService = driver.graphDatabaseService
            ProcedureTestUtil.registerProcedure(databaseService, SpatialProcedures::class.java)
            val spatialPlugin = SpatialPlugin()
            spatialPlugin.addSimplePointLayer(databaseService, layerName, "latitude", "longitude")
        } else {
            throw UnsupportedOperationException("Expected an embedded Neo4j instance, but was " + driver.javaClass.name)
        }
    }
}

и дополнительно

class ProcedureTestUtil {

    companion object {
        @JvmStatic
        var registeredProcedures: MutableList<Class<*>> = ArrayList()

        @JvmStatic
        @Throws(KernelException::class)
        fun registerProcedure(db: GraphDatabaseService, procedure: Class<*>) {
            val proceduresService = (db as GraphDatabaseAPI).dependencyResolver.resolveDependency(Procedures::class.java)
            proceduresService.register(procedure)
            registeredProcedures.add(procedure)
        }
    }
}

вы должны запустить ваши тесты, еслиLocationServiceTest extends AbstractIntegrationTestsWithProcedures,

Другие вопросы по тегам