While starting maven with test parameters, I get the above mentioned exception. While creating the integration test deployment, I get the following:
org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYEJB0466: Failed to process business interfaces for EJB class class ..contract.ContractMockService
The concerning class looks like this:
package ..integration.bestand.contract;
import java.time.LocalDate;
import java.util.ArrayList;
import javax.ejb.Local;
import javax.ejb.Stateless;
import org.apache.deltaspike.core.api.exclude.Exclude;
import org.apache.deltaspike.core.api.projectstage.ProjectStage;
...
#Exclude(ifProjectStage = {
ProjectStage.Production.class,
ProjectStage.Staging.class,
..Integration.class,
..Qs.class,
..PatchQs.class
})
#Stateless
#Local(IContractIntService.class)
public class ContractMockService implements IContractIntService {
...
return ContractBuilder.build();
}
}
The interface IContractIntService looks like:
package ..integration.bestand.contract;
import javax.ejb.Local;
...
#Local
public interface IContractIntService {
public enum State {
SUCCESS,
UNKNOWN_ERROR,
NOT_FOUND;
// TODO: Stati für Fehler hier definieren
}
//Interface comment
Result<State, ContractDTO> retrieveContract(String contractIdentifier);
}
Note: The interface is in another project which is included via maven.
The Test looks like this:
package ..api.contractregistration.service;
import static org.hamcrest.CoreMatchers.any;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.logging.Logger;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TestWatcher;
import org.junit.runner.RunWith;
import ..core.test.IntegrationTest;
#RunWith(Arquillian.class)
#Category(IntegrationTest.class)
public class ContractRegistrationIntegrationTest {
protected final Logger log = Logger.getLogger(ContractRegistrationIntegrationTest.class.getCanonicalName());
#Rule
public TestWatcher watcher = new TestWatcher() {
#Override
protected void starting(org.junit.runner.Description description) {
log.info(String.format("---> Starting test: %s", description));
}
#Override
protected void failed(Throwable e, org.junit.runner.Description description) {
log.info(String.format("<--- Test failed: %s", description));
}
#Override
protected void succeeded(org.junit.runner.Description description) {
log.info(String.format("<--- Test succeeded: %s", description));
}
};
#Deployment
public static WebArchive createDeployment() {
WebArchive result = ShrinkWrap.create(WebArchive.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml")
.addPackages(true, "..ejb.portal")
.addPackages(true, "..core")
.deletePackages(true, "..core.config.deltaspike")
.addPackages(true, "..integration")
.addPackages(true, "..api")
.addPackages(true, "org.apache.deltaspike.core")
.addPackages(true, "..ejb.util");
System.out.println("########## TEST DEPLOYMENT########" + result.toString(true));
return result;
}
#Test
public void test() {
String tempPw = "bla"; // result.getDto();
assertThat(tempPw, any(String.class));
}
}
The remarkable thing about this test is, that I'm not even using anything of the MockService inside a test.
The maven configuration looks like this:
Goals: clean test -Parq-wildfly-managed
JRE VM Arguments: -Djboss.home="myLocalWildflyDirectory"
JAVA_HOME is set to jdk8.
Last thing is my pom, specifically the part of the container "arq-wildfly-managed":
...
<profile>
<!-- An optional Arquillian testing profile that executes tests in your WildFly instance, e.g. for build server -->
<!-- This profile will start a new WildFly instance, and execute the test, shutting it down when done -->
<!-- Run with: mvn clean test -Parq-wildfly-managed -->
<id>arq-wildfly-managed</id>
<dependencies>
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.ivi.torino</groupId>
<artifactId>torino-integration-bestand-mock-ejb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.ivi.torino</groupId>
<artifactId>torino-integration-docservice-mock-ejb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.ivi.torino</groupId>
<artifactId>torino-integration-bestand-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</profile>
...
A normal maven build with clean verify package install (just no test included) builds successfully.
Note: For this post, I renamed the packages to exclude company specializations.
Similar errors suggest correcting the ShrinkWrap deployment, but I included virtually every package there is and even tried to explicitly include the interface-class. But still, the same error remains.
What could cause this?
Try this in the Test (ShrinkWrap):
.addAsResource(new StringAsset("org.apache.deltaspike.ProjectStage=IntegrationTest"), "META-INF/apache-deltaspike.properties")
And change your Exclude to this:
#Exclude(exceptIfProjectStage = ProjectStage.IntegrationTest.class)
If you need to exclude additional Stages, add them to this very exclude statement
A bit late, but a better solution to the problem was the following:
Inside the ShrinkWrap deployment, a use of the shrinkwrap maven resolver is needed. So, instead of
.addPackages(true, "org.apache.deltaspike.core")
inside the creation of result, use the maven resolver. Should look something like this:
ShrinkWrap
.create(WebArchive.class, "test.war")
.addAsLibraries(
resolver.artifact("org.apache.deltaspike.core")
.resolveAsFiles());
The artifact is the maven artifactId. this will return another .war. multiple .wars (created from the resolver or the way you see in the original question) can be merged. This merged .war then has to be returned from the deployment method.
Reason behind this:
External includes (in this case deltaspike) are missing resources once you import them via ShrinkWrap.create.*.addAsPackages.., so this should only be used for internal project packages. To use the maven resolver, you can include the following in the .pom-file:
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
credits to dzone.com for the maven resolver code snippets. I'm currently working on another project, so I can't show the original code, but it was very similar to this.
Maybe this solution will help someone in the future.
Related
Can I have a sample routine (that has been tested) on latest T24/Transact release using Temenos Java APIs?
As per Temenos, Infobasic routines cannot be used anymore if EXTENSIBLE.CUSTOMISATION flag is set to Y in SPF.
Here is an actual, working sample that works in R20 - it is a sample of ENQUIRY build routine:
package com.bank;
import java.util.List;
import com.temenos.api.TStructure;
import com.temenos.t24.api.complex.eb.enquiryhook.FilterCriteria;
import com.temenos.t24.api.complex.eb.enquiryhook.EnquiryContext;
import com.temenos.t24.api.hook.system.Enquiry;
public class EnqBuildRoutineTest extends Enquiry {
#Override
public List<FilterCriteria> setFilterCriteria(List<FilterCriteria> filterCriteria, EnquiryContext enquiryContext) {
FilterCriteria criteria = new FilterCriteria();
criteria.setFieldname("SECTOR.CODE");
criteria.setOperand("LK");
criteria.setValue("2...");
filterCriteria.add(criteria);
return filterCriteria;
}
}
In case you are using maven, you can use these dependencies in pom.xml:
<dependency>
<groupId>com.temenos</groupId>
<artifactId>api</artifactId>
<scope>system</scope>
<systemPath>c:/Temenos/R20_MB/TAFJ/lib/TAFJClient.jar</systemPath>
<version>1</version>
</dependency>
<dependency>
<groupId>com.temenos</groupId>
<artifactId>EnquiryHook</artifactId>
<scope>system</scope>
<systemPath>c:/Temenos/R20_MB/bnk/t24lib/EB_EnquiryHook.jar</systemPath>
<version>1</version>
</dependency>
Once you have packaged it inside JAR and placed in your Classpath, you need to create EB.API record with "Source Type = Method" and specify the overriden setFilterCriteria as the method inside EB.API record. You also need to specify Class name (EnqBuildRoutineTest in this case) and package name (com.bank).
My question is a variation of this one.
Since my Java Web-app project requires a lot of read filters/queries and interfaces with tools like GridFS, I'm struggling to think of a sensible way to employ MongoDB in the way the above solution suggests.
Therefore, I'm considering running an embedded instance of MongoDB alongside my integration tests. I'd like it to start up automatically (either for each test or the whole suite), flush the database for every test, and shut down at the end. These tests might be run on development machines as well as the CI server, so my solution will also need to be portable.
Can anyone with more knowledge on MongoDB help me get idea of the feasibility of this approach, and/or perhaps suggest any reading material that might help me get started?
I'm also open to other suggestions people might have on how I could approach this problem...
I have found Embedded MongoDB library which looks quite promising and does what you have asked for.
Currently supports MongoDB versions: 1.6.5 to 3.1.6, provided the binaries are still available from the configured mirror.
Here is short example of use, which I have just tried and it works perfectly:
public class EmbeddedMongoTest {
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private Mongo mongo;
#Before
public void beforeEach() throws Exception {
MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
mongodExe = runtime.prepare(new MongodConfig(Version.V2_3_0, 12345, Network.localhostIsIPv6()));
mongod = mongodExe.start();
mongo = new Mongo("localhost", 12345);
}
#After
public void afterEach() throws Exception {
if (this.mongod != null) {
this.mongod.stop();
this.mongodExe.stop();
}
}
#Test
public void shouldCreateNewObjectInEmbeddedMongoDb() {
// given
DB db = mongo.getDB(DATABASE_NAME);
DBCollection col = db.createCollection("testCollection", new BasicDBObject());
// when
col.save(new BasicDBObject("testDoc", new Date()));
// then
assertThat(col.getCount(), Matchers.is(1L));
}
}
Here's an updated (for 2022) version of the accepted answer from #rozky (a lot has been changed in both the Mongo and Embedded MongoDB libraries).
package com.example.mongo;
import com.mongodb.BasicDBObject;
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.MongodConfig;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import java.util.Date;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class EmbeddedMongoTest {
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private MongoClient mongo;
#Before
public void beforeEach() throws Exception {
MongodStarter starter = MongodStarter.getDefaultInstance();
String bindIp = "localhost";
int port = 12345;
MongodConfig mongodConfig = MongodConfig.builder()
.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("testCollection");
MongoCollection<BasicDBObject> col = db.getCollection("testCollection", BasicDBObject.class);
// when
col.insertOne(new BasicDBObject("testDoc", new Date()));
// then
assertEquals(1L, col.countDocuments());
}
}
There is Foursquare product Fongo.
Fongo is an in-memory java implementation of mongo. It intercepts calls to the standard mongo-java-driver for finds, updates, inserts, removes and other methods. The primary use is for lightweight unit testing where you don't want to spin up a mongo process.
If you're using Maven you may be interested in a plugin I've created that wraps the flapdoodle.de 'embedded mongo' API:
embedmongo-maven-plugin
It provides a start goal that you can use to start any version of MongoDB you want (e.g. during pre-integration-test), and a stop goal that will stop MongoDB (e.g. during post-integration-test).
The real benefit of using this plugin over others is that there is no requirement for MongoDB to be installed beforehand. MongoDB binaries are downloaded and stored in ~/.embedmongo for future builds.
If you are using sbt and specs2, I wrote the same kind of wrapper for embedmongo
https://github.com/athieriot/specs2-embedmongo
with spring-boot 1.3 you can use EmbeddedMongoAutoConfiguration
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>${embedded-mongo.version}</version>
</dependency>
MongoConfig
#Configuration
#EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
You can run MongoDB in memory as of version 3.2.6. From the site:
Starting in MongoDB Enterprise version 3.2.6, the in-memory storage
engine is part of general availability (GA) in the 64-bit builds.
Other than some metadata and diagnostic data, the in-memory storage
engine does not maintain any on-disk data, including configuration
data, indexes, user credentials, etc.
Not just for unit testing, but also explained how to use inmemory mongodb with rest api.
maven dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
=============================================================================
application.properties
server.port = 8080
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost
=============================================================================
UserRepository.java
public interface UserRepository extends MongoRepository{
}
for reference and all java code use below link:(step by step explanation)
https://www.youtube.com/watch?v=2Tq2Q7EzhSA&t=7s
Performances are better when executing mongod with storageEngine='ephemeralForTest'
new MongodConfigBuilder()
.version(Version.Main.PRODUCTION)
.cmdOptions(new MongoCmdOptionsBuilder()
.useStorageEngine("ephemeralForTest")
.build())
.net(new Net("localhost", port, Network.localhostIsIPv6()))
.build()
To run Embedded mongodb for integration test following are the maven dependency needed:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
Try using below code snipped for EmbeddedMongoAutoConfiguration:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class EmbeddedMongoApplication {
public static void main(String[] args) {
System.setProperty("os.arch", "x86_64");
SpringApplication.run(EmbeddedMongoApplication.class, args);
}
#Bean
public EmbeddedMongoAutoConfiguration embeddedMongoAutoConfiguration(MongoProperties mongoProperties) {
return new EmbeddedMongoAutoConfiguration(mongoProperties);
}
}
Note:
Embedded mongodb will be downloaded to below Path. So take into consideration that path have proper permission.
Linux : $HOME/.embedmongo/linux/mongodb-linux-x86_64-3.2.2.tgz
Windows : C:\Users\<username>\.embedmongo\win32\mongodb-win32-x86_64-3.x.x.zip
In production, you will be using a real database.
If you want your tests to reflect how your product behaves in production, use a real instance of Mongo.
A fake implementation may not behave exactly the same as a real one. When testing, you should strive for correctness. Speed of execution comes second.
#Before and #After methods of hooks are not running while running the Runner class.
I am using the dependencies:
cucumber-java 4.3.0
cucumber-jvm 4.3.0
All steps in stepdef file are running fine except hooks. Is it some issue with latest cucumber version?
public class Hooks {
#Before
public void beforeHooks() {
System.out.println("Run Before Scenario");
}
#After
public void afterHooks() {
System.out.println("Run After Scenario");
}
First Make sure you are using cucumber.api.java.Before (interface) rather than org.junit.Before as Cucumber will not process JUnit annotations.
#Before - import cucumber.api.java.Before;
#After - import cucumber.api.java.After;
Hope we are on the same page here and let's move further without making any delay.
Second lets understand in case your STEPS IMPLEMENTATION METHODS and HOOK CLASS is in the same package then we do not need to specify path of Hooks class additionally in the glue option of runner. In my case, i do have both in same package so we need to set only one package.
But if they are in the different packages then please include the package of the Hooks class in the glue option of the runner file.
Cucumber Runner :
package com.jacksparrow.automation.suite.runner;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(features = "classpath:features/functional/",
glue = {"com.jacksparrow.automation.steps_definitions.functional" },
plugin = { "pretty","json:target/cucumber-json/cucumber.json",
"junit:target/cucumber-reports/Cucumber.xml", "html:target/cucumber-reports"},
tags = { "#BAMS_Submitted_State_Guest_User" },
strict = false,
dryRun = false,
monochrome = true)
public class RunCukeTest {
}
Key Point: We shall not mix direct & transitive dependencies specially their versions! Doing so can cause unpredictable outcome. You can add below set of cucumber minimal dependencies.
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
I am very new to Apache Spark framework, trying to setup my first jUnit like follows:
package com.sample.ccspark;
import com.holdenkarau.spark.testing.SharedJavaSparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.junit.Test;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
public class SimpleTest extends SharedJavaSparkContext {
#Test
public void initializationWorks() {
List<Integer> list = asList(1, 2, 3, 4);
JavaRDD<Integer> rdd = jsc().parallelize(list);
assertThat(rdd.count(), is(list.size()));
}
}
with the following dependencies in the pom.xml
<dependency>
<groupId>com.holdenkarau</groupId>
<artifactId>spark-testing-base_2.11</artifactId>
<version>2.2.0_0.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.10</artifactId>
<version>2.2.0</version>
</dependency>
everything happily compiles, however when running I am getting the following exception:
Exception in thread "dispatcher-event-loop-6" java.lang.NoClassDefFoundError:
scala/runtime/AbstractPartialFunction$mcVL$sp
I do not have Spark or Scala installed locally yet, was under impression that testing framework should take care of all dependencies. Is there something I am missing here?
In the artifacts names
<artifactId>spark-testing-base_2.11</artifactId>
<artifactId>spark-core_2.10</artifactId>
the last number is the version of Scala. I guess you should select only one for both cases.
My question is a variation of this one.
Since my Java Web-app project requires a lot of read filters/queries and interfaces with tools like GridFS, I'm struggling to think of a sensible way to employ MongoDB in the way the above solution suggests.
Therefore, I'm considering running an embedded instance of MongoDB alongside my integration tests. I'd like it to start up automatically (either for each test or the whole suite), flush the database for every test, and shut down at the end. These tests might be run on development machines as well as the CI server, so my solution will also need to be portable.
Can anyone with more knowledge on MongoDB help me get idea of the feasibility of this approach, and/or perhaps suggest any reading material that might help me get started?
I'm also open to other suggestions people might have on how I could approach this problem...
I have found Embedded MongoDB library which looks quite promising and does what you have asked for.
Currently supports MongoDB versions: 1.6.5 to 3.1.6, provided the binaries are still available from the configured mirror.
Here is short example of use, which I have just tried and it works perfectly:
public class EmbeddedMongoTest {
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private Mongo mongo;
#Before
public void beforeEach() throws Exception {
MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
mongodExe = runtime.prepare(new MongodConfig(Version.V2_3_0, 12345, Network.localhostIsIPv6()));
mongod = mongodExe.start();
mongo = new Mongo("localhost", 12345);
}
#After
public void afterEach() throws Exception {
if (this.mongod != null) {
this.mongod.stop();
this.mongodExe.stop();
}
}
#Test
public void shouldCreateNewObjectInEmbeddedMongoDb() {
// given
DB db = mongo.getDB(DATABASE_NAME);
DBCollection col = db.createCollection("testCollection", new BasicDBObject());
// when
col.save(new BasicDBObject("testDoc", new Date()));
// then
assertThat(col.getCount(), Matchers.is(1L));
}
}
Here's an updated (for 2022) version of the accepted answer from #rozky (a lot has been changed in both the Mongo and Embedded MongoDB libraries).
package com.example.mongo;
import com.mongodb.BasicDBObject;
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.MongodConfig;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import java.util.Date;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class EmbeddedMongoTest {
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private MongoClient mongo;
#Before
public void beforeEach() throws Exception {
MongodStarter starter = MongodStarter.getDefaultInstance();
String bindIp = "localhost";
int port = 12345;
MongodConfig mongodConfig = MongodConfig.builder()
.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("testCollection");
MongoCollection<BasicDBObject> col = db.getCollection("testCollection", BasicDBObject.class);
// when
col.insertOne(new BasicDBObject("testDoc", new Date()));
// then
assertEquals(1L, col.countDocuments());
}
}
There is Foursquare product Fongo.
Fongo is an in-memory java implementation of mongo. It intercepts calls to the standard mongo-java-driver for finds, updates, inserts, removes and other methods. The primary use is for lightweight unit testing where you don't want to spin up a mongo process.
If you're using Maven you may be interested in a plugin I've created that wraps the flapdoodle.de 'embedded mongo' API:
embedmongo-maven-plugin
It provides a start goal that you can use to start any version of MongoDB you want (e.g. during pre-integration-test), and a stop goal that will stop MongoDB (e.g. during post-integration-test).
The real benefit of using this plugin over others is that there is no requirement for MongoDB to be installed beforehand. MongoDB binaries are downloaded and stored in ~/.embedmongo for future builds.
If you are using sbt and specs2, I wrote the same kind of wrapper for embedmongo
https://github.com/athieriot/specs2-embedmongo
with spring-boot 1.3 you can use EmbeddedMongoAutoConfiguration
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>${embedded-mongo.version}</version>
</dependency>
MongoConfig
#Configuration
#EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
You can run MongoDB in memory as of version 3.2.6. From the site:
Starting in MongoDB Enterprise version 3.2.6, the in-memory storage
engine is part of general availability (GA) in the 64-bit builds.
Other than some metadata and diagnostic data, the in-memory storage
engine does not maintain any on-disk data, including configuration
data, indexes, user credentials, etc.
Not just for unit testing, but also explained how to use inmemory mongodb with rest api.
maven dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
=============================================================================
application.properties
server.port = 8080
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost
=============================================================================
UserRepository.java
public interface UserRepository extends MongoRepository{
}
for reference and all java code use below link:(step by step explanation)
https://www.youtube.com/watch?v=2Tq2Q7EzhSA&t=7s
Performances are better when executing mongod with storageEngine='ephemeralForTest'
new MongodConfigBuilder()
.version(Version.Main.PRODUCTION)
.cmdOptions(new MongoCmdOptionsBuilder()
.useStorageEngine("ephemeralForTest")
.build())
.net(new Net("localhost", port, Network.localhostIsIPv6()))
.build()
To run Embedded mongodb for integration test following are the maven dependency needed:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
Try using below code snipped for EmbeddedMongoAutoConfiguration:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class EmbeddedMongoApplication {
public static void main(String[] args) {
System.setProperty("os.arch", "x86_64");
SpringApplication.run(EmbeddedMongoApplication.class, args);
}
#Bean
public EmbeddedMongoAutoConfiguration embeddedMongoAutoConfiguration(MongoProperties mongoProperties) {
return new EmbeddedMongoAutoConfiguration(mongoProperties);
}
}
Note:
Embedded mongodb will be downloaded to below Path. So take into consideration that path have proper permission.
Linux : $HOME/.embedmongo/linux/mongodb-linux-x86_64-3.2.2.tgz
Windows : C:\Users\<username>\.embedmongo\win32\mongodb-win32-x86_64-3.x.x.zip
In production, you will be using a real database.
If you want your tests to reflect how your product behaves in production, use a real instance of Mongo.
A fake implementation may not behave exactly the same as a real one. When testing, you should strive for correctness. Speed of execution comes second.