JUnit 测试 MongoDB Spring Boot

Posted

技术标签:

【中文标题】JUnit 测试 MongoDB Spring Boot【英文标题】:JUnit test MongoDB SpringBoot 【发布时间】:2019-10-26 14:21:06 【问题描述】:

我正在尝试在我的应用程序 SpringBoot 中使用 MongoDB embebed 进行测试,但我在运行我的应用程序时出现错误,这是我第一次,我从未使用 Springboot、mongodb、junit 进行测试...

首先我在我的 pom.xml 中添加这个依赖:

    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>1.50.2</version>
        <scope>runtime</scope>
    </dependency>

有了这个依赖,我将嵌入 mongoDB(但我不知道这个版本是否正确......)

然后我创建了两个类java:

@Configuration
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class))
@EnableAutoConfiguration
public class TestApplicationConfiguration 

    @Bean 
    GenerarCsv service() 
        return new GenerarCsvImpl();
    

在这个类中,我有我的接口,我将生成我的实现,现在是我的 2º 类 java:

import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.batch.DesarrolloBatch.model.Documento;
import com.batch.DesarrolloBatch.persistence.DocumentoRepository;
import com.batch.DesarrolloBatch.service.interfaces.GenerarCsv;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;


@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@SpringBootTest(classes=TestApplicationConfiguration.class)
public class GenerarDocumentoTest 

    @Autowired
    private GenerarCsv service; 

    @Autowired
    private DocumentoRepository repository;


    private static final String DATABASE_NAME = "documento";

    private MongodExecutable mongodExe;
    private MongodProcess mongod;
    private MongoClient mongo;

    @Before
    public void beforeEach() throws Exception 
        MongodStarter starter = MongodStarter.getDefaultInstance();
        String bindIp = "localhost";
        int port = 27017;
        IMongodConfig mongodConfig = new MongodConfigBuilder()
        .version(Version.Main.PRODUCTION)
        .net(new Net(bindIp, port, Network.localhostIsIPv6()))
        .build();
        this.mongodExe = starter.prepare(mongodConfig);
        this.mongod = mongodExe.start();
        this.mongo = new MongoClient(bindIp, port);
    

    @After
    public void afterEach() throws Exception 
        if (this.mongod != null) 
            this.mongod.stop();
            this.mongodExe.stop();
        
    

    @Test
    public void shouldCreateNewObjectInEmbeddedMongoDb() 
        // given
        MongoDatabase db = mongo.getDatabase(DATABASE_NAME);
        db.createCollection("documento");
        MongoCollection<Documento> col = db.getCollection("documento", Documento.class);

        // when
        Documento doc = new Documento();
        doc.set_id("999999999999999999999999");
        col.insertOne(doc);

        // then
        assertEquals(1L, col.countDocuments());
    


好的,在这个类中,我在内存中使用我的 mongoDB 创建了 conxión,然后我尝试在 mongDB 中插入一个对象类型文档,最后我问我是否在我的 mongoDB 中注册了 1 个,但是,当我尝试运行时出现错误这个应用程序 ->

 at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117) ~[spring-test-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 26 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'embeddedMongoServer' defined in class path resource [org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.flapdoodle.embed.mongo.MongodExecutable]: Factory method 'embeddedMongoServer' threw exception; nested exception is de.flapdoodle.embed.process.exceptions.DistributionException: java.io.IOException: Could not open inputStream for http://downloads.mongodb.org/win32/mongodb-win32-x86_64-3.5.5.zip
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:607) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    ... 26 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.flapdoodle.embed.mongo.MongodExecutable]: Factory method 'embeddedMongoServer' threw exception; nested exception is de.flapdoodle.embed.process.exceptions.DistributionException: java.io.IOException: Could not open inputStream for http://downloads.mongodb.org/win32/mongodb-win32-x86_64-3.5.5.zip
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:607) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
Caused by: de.flapdoodle.embed.process.exceptions.DistributionException: java.io.IOException: Could not open inputStream for http://downloads.mongodb.org/win32/mongodb-win32-x86_64-3.5.5.zip
    at de.flapdoodle.embed.process.runtime.Starter.prepare(Starter.java:68) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
    at org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration.embeddedMongoServer(EmbeddedMongoAutoConfiguration.java:116) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration$$EnhancerBySpringCGLIB$$67c9dfd6.CGLIB$embeddedMongoServer$1(<generated>) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration$$EnhancerBySpringCGLIB$$67c9dfd6$$FastClassBySpringCGLIB$$8d580d09.invoke(<generated>) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration$$EnhancerBySpringCGLIB$$67c9dfd6.embeddedMongoServer(<generated>) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_171]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_171]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_171]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_171]
    ... 26 more
Caused by: java.io.IOException: Could not open inputStream for http://downloads.mongodb.org/win32/mongodb-win32-x86_64-3.5.5.zip
    at de.flapdoodle.embed.process.store.Downloader.downloadInputStream(Downloader.java:131) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
    at de.flapdoodle.embed.process.store.Downloader.download(Downloader.java:69) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
    at de.flapdoodle.embed.process.store.ArtifactStore.checkDistribution(ArtifactStore.java:66) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
    at de.flapdoodle.embed.process.store.ExtractedArtifactStore.checkDistribution(ExtractedArtifactStore.java:60) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
    at de.flapdoodle.embed.process.runtime.Starter.prepare(Starter.java:55) ~[de.flapdoodle.embed.process-1.50.1.jar:?]
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[?:1.8.0_171]
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) ~[?:1.8.0_171]
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[?:1.8.0_171]

如果我在我的导航中复制这些链接“htpp..... .zip”,我可以下载这些.zip,那么我不知道为什么SpringBoot不能下载.zip。

最后,我想提醒一下,我不知道这样做,我是复制并粘贴其他人的帖子在谷歌。如果有人知道如何在 Springboot 中使用 mongoDB 进行 Junit 测试,那是我的最终目标。这是我的第一次。谢谢。

编辑:

我改变了我的依赖:

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

现在当我运行我的应用程序时,她正在下载,但总是 0% 永远不会启动...

019-06-12 09:45:02.242  INFO 14372 --- [           main] c.b.D.GenerarDocumentoTest               : The following profiles are active: test
2019-06-12 09:45:03.108  INFO 14372 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-06-12 09:45:03.282  INFO 14372 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 166ms. Found 1 repository interfaces.
2019-06-12 09:45:04.005  INFO 14372 --- [           main] o.s.b.a.m.e.EmbeddedMongo                : Download Version3.5.5:Windows:B64 : starting...
2019-06-12 09:45:06.621  INFO 14372 --- [           main] o.s.b.a.m.e.EmbeddedMongo                : Download Version3.5.5:Windows:B64 : DownloadSize: 245893992
2019-06-12 09:45:08.809  INFO 14372 --- [           main] o.s.b.a.m.e.EmbeddedMongo                : Download Version3.5.5:Windows:B64 : 0 %

【问题讨论】:

根据异常,很明显它正在尝试下载 MongoDB 并且抛出了 SocketTimeoutException。我想这可能只是暂时的网络故障导致从互联网下载。再试一次!! 您可以使用以下方式自定义您的下载网址:github.com/flapdoodle-oss/…。您可以手动下载此文件并将其放置在您可访问的网络服务器中进行下载。 我从昨天开始就在尝试这个..... 另一种可能是您的防火墙阻止了您的 java 运行时的下载访问。检查暂时禁用防火墙是否可以解决问题。或者按照 Sunil 上面的建议,先手动下载 jar。 我编辑了我的帖子,其他部分,我不知道下载 git 并实现这些...谢谢 【参考方案1】:

方法 de.flapdoodle.embed.process.store.LocalArtifactStore.getArtifact(IDownloadConfig runtime, Distribution distribution) 检查用户的本地文件夹,查看本地是否已经存在分发文件。如果该方法不存在,该方法将返回 null。

然后调用方法将尝试下载文件,超时,并抛出一个包装 IO 异常的 de.flapdoodle.embed.process.distribution.Distributon.DistributionException。

这会中断 Spring Boot 运行时注入,并且所有依赖于此的测试都会失败。

下载文件http://downloads.mongodb.org/win32/mongodb-win32-x86_64-3.5.5.zip

在 Windows 上,将其复制到您的用户文件夹,如下所示: c:\users\your_user_name\.embeddedmongo\win32\mongodb-win32-x86_64-3.5.5.zip

现在运行您的测试,它会将嵌入式服务器可执行文件提取到 c:\users\your_user_name\.embeddedmongo\extracted\Windows-B64--3.5.5\extractmongod.exe

您的测试现在应该可以正常运行了。

【讨论】:

谢谢你解决了我的问题,请问下载失败有什么原因吗?

以上是关于JUnit 测试 MongoDB Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

spring框架学习spring与junit整合测试

spring-cloud-stream 与测试中的 spring-boot-data-mongodb 冲突

记录一下Junit测试MongoDB,获取MongoTemplate

MongoDB 单元测试

如何使 junit 测试在 springboot 应用程序中使用嵌入式 mongoDB?

Spring boot Embedded MongoDb 数据预填充