使用 neo4j-spatial 密码查询与 SDN4 存储库进行集成测试
Integration testing with SDN4 repositories using neo4j-spatial cypher queries
我开始在我的一些代码中使用 neo4j-spatial。我认为我可以通过将空间服务器库作为 Maven 依赖项包含在我的项目中来集成测试 neo4j-spatial 代码。但这对我不起作用。我在任何地方都找不到任何文档。
如何让我的集成测试工作?
有人有什么建议吗? :)
为了让大家了解我在做什么,我在下面粘贴了我的控制器、服务和存储库代码的一部分,最后发布的代码是我的测试,它不适用于嵌入式 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 */
}
}
SDN 4 中还没有提供空间功能。如果您集成了 neo4j-spatial 库,那么您目前唯一的选择就是直接使用它——将没有存储库支持等。
但是,空间集成工作目前正在进行中,因此应该在下一个版本中引入一些基本功能。
我们正在使用 SDN 4.1.2、OGM 2.0.3,我的测试使用此设置:
使用 the description on the github page 添加了 maven 依赖项。在撰写此评论时,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
.
我开始在我的一些代码中使用 neo4j-spatial。我认为我可以通过将空间服务器库作为 Maven 依赖项包含在我的项目中来集成测试 neo4j-spatial 代码。但这对我不起作用。我在任何地方都找不到任何文档。
如何让我的集成测试工作?
有人有什么建议吗? :)
为了让大家了解我在做什么,我在下面粘贴了我的控制器、服务和存储库代码的一部分,最后发布的代码是我的测试,它不适用于嵌入式 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 */
}
}
SDN 4 中还没有提供空间功能。如果您集成了 neo4j-spatial 库,那么您目前唯一的选择就是直接使用它——将没有存储库支持等。 但是,空间集成工作目前正在进行中,因此应该在下一个版本中引入一些基本功能。
我们正在使用 SDN 4.1.2、OGM 2.0.3,我的测试使用此设置:
使用 the description on the github page 添加了 maven 依赖项。在撰写此评论时,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
.