java - 使用 Spring Data Embedded Mongo 在 Mongo 数据库中导入 JSON 文件

标签 java mongodb spring-boot spring-data

我正在尝试编写一些与需要从 MongoDB 中提取数据的方法相关的集成测试。详细地说,我正在使用 Embedded Mongo由 Spring Data 项目给出。 Flapdoodle明确提供了嵌入式mongo .

我需要将一些 json 文件导入嵌入式 Mongo。我查看了 flapdoodle 提供的测试,但我无法理解它们如何与 Spring Data + Spring Boot 提供的魔法 集成。

任何人都可以发布一些澄清片段吗?

最佳答案

您可以创建一个在每次测试前后运行的 junit 规则 ( ExternalResource)。检查 MongoEmbeddedRule 类以了解实现细节。

集成测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public abstract class TestRunner {

    @Autowired
    protected MongoTemplate mongoTemplate;

    @Rule
    public MongoEmbeddedRule mongoEmbeddedRule = new MongoEmbeddedRule(this);

外部资源规则:

public class MongoEmbeddedRule extends ExternalResource {

    private final Object testClassInstance;
    private final Map<String, Path> mongoCollectionDataPaths;
    private final String fieldName;
    private final String getterName;

    public MongoEmbeddedRule(final Object testClassInstance) {
        this(testClassInstance, "mongoTemplate", "getMongoTemplate");
    }

    protected MongoEmbeddedRule(final Object testClassInstance, final String fieldName, final String getterName) {
        this.fieldName = fieldName;
        this.getterName = getterName;
        this.testClassInstance = testClassInstance;
        this.mongoCollectionDataPaths = mongoExtendedJsonFilesLookup();
    }

    @Override
    protected void before() {
        dropCollections();
        createAndPopulateCollections();
    }

    @Override
    protected void after() {
    }

    protected Set<String> getMongoCollectionNames() {
        return mongoCollectionDataPaths.keySet();
    }

    public void dropCollections() {
        getMongoCollectionNames().forEach(collectionName -> getMongoTemplate().dropCollection(collectionName));
    }

    protected void createAndPopulateCollections() {
        mongoCollectionDataPaths.forEach((key, value) -> insertDocumentsFromMongoExtendedJsonFile(value, key));
    }

    protected MongoTemplate getMongoTemplate() {
        try {
            Object value = ReflectionTestUtils.getField(testClassInstance, fieldName);
            if (value instanceof MongoTemplate) {
                return (MongoTemplate) value;
            }
            value = ReflectionTestUtils.invokeGetterMethod(testClassInstance, getterName);
            if (value instanceof MongoTemplate) {
                return (MongoTemplate) value;
            }
        } catch (final IllegalArgumentException e) {
            // throw exception with dedicated message at the end
        }
        throw new IllegalArgumentException(
                String.format(
                        "%s expects either field '%s' or method '%s' in order to access the required MongoTemmplate",
                        this.getClass().getSimpleName(), fieldName, getterName));
    }

    private Map<String, Path> mongoExtendedJsonFilesLookup() {
        Map<String, Path> collections = new HashMap<>();
        try {
            Files.walk(Paths.get("src","test","resources","mongo"))
                    .filter(Files::isRegularFile)
                    .forEach(filePath -> collections.put(
                            filePath.getFileName().toString().replace(".json", ""),
                            filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return collections;
    }

    private void insertDocumentsFromMongoExtendedJsonFile(Path path, String collectionName) {
        try {
            List<Document> documents = new ArrayList<>();
            Files.readAllLines(path).forEach(l -> documents.add(Document.parse(l)));
            getMongoTemplate().getCollection(collectionName).insertMany(documents);
            System.out.println(documents.size() + " documents loaded for " + collectionName + " collection.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

json 文件 (names.json) MongoDB Extended JSON ,其中每个文档都在一行中,集合名称是不带扩展名的文件名。

{ "_id" : ObjectId("594d324d5b49b78da8ce2f28"), "someId" : NumberLong(1), "name" : "Some Name 1", "lastModified" : ISODate("1970-01-01T00:00:00Z")}
{ "_id" : ObjectId("594d324d5b49b78da8ce2f29"), "someId" : NumberLong(2), "name" : "Some Name 2", "lastModified" : ISODate("1970-01-01T00:00:00Z")}

关于java - 使用 Spring Data Embedded Mongo 在 Mongo 数据库中导入 JSON 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40378812/

相关文章:

java - Android - NoClassDefFoundError

java - 添加 Action 监听器的语法

java - java中多线程访问多个共享资源

ios - spring boot OAuth2 + 手机客户端(密码和FB登录)

java - Vue JS 和 Spring Boot 跨源错误

java - 使用 spring-boot 应用程序自动压缩/优化图像

java - ViewPager 中 Fragment 内的 TextView 在方向更改时为空

mongodb - 机器 ID/主机名如何映射/解映射到对象 ID 中的 3 个字节?

mysql - 如何在同一个 NodeJs 服务器上使用 Mysql 和 MongoDB?

java - MongoDB 的 JMX 注册错误