SpringRestDocs and mocking MongoDB - java

I'm trying to generate API documentation using SpringRestDocs and SpringBootTest and MockMVC.
Our service uses MongoDB as storage and we have various services that talk to MongoDB using repositories.
In my test I'm mocking the services to not rely on MongoDB or data.
Though my tests run fine only if I've a local mongo running on my machine, otherwise tests fail because org.mongodb.driver.cluster is not able to connect.
Here is the error I get:
018-03-06 11:42:05.620 INFO 56095 --- [localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.connection.SocketStream.open(SocketStream.java:63) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113) ~[mongodb-driver-core-3.4.3.jar:na]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_144]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_144]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_144]
at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:57) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.SocketStream.open(SocketStream.java:58) ~[mongodb-driver-core-3.4.3.jar:na]
... 3 common frames omitted
2018-03-06 11:42:05.724 INFO 56095 --- [ main] org.mongodb.driver.cluster : No server chosen by WritableServerSelector from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, serverDescriptions=[ServerDescription{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused (Connection refused)}}]}. Waiting for 30000 ms before timing out
I would like to totally bypass MongoDB because I don't need it to build my documentation.
I've tried to use #MockBean on all the repositories that use Mongo and disable autoconfiguration, but still not working properly
Any suggestion on what shoudl I do to mock the MongoDB client/template?
Here is my ApiDocumentation.java class, without
package uk.ac.ebi.biosamples.docs;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Rule;
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.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.*;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import uk.ac.ebi.biosamples.model.Curation;
import uk.ac.ebi.biosamples.model.CurationLink;
import uk.ac.ebi.biosamples.model.Sample;
import uk.ac.ebi.biosamples.model.filter.Filter;
import uk.ac.ebi.biosamples.service.*;
import java.util.Collections;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ApiDocumentation {
#Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
#Autowired
private WebApplicationContext context;
private ObjectMapper mapper;
#MockBean
private SamplePageService samplePageService;
#MockBean
private SampleService sampleService;
#MockBean
CurationPersistService curationPersistService;
#MockBean
CurationReadService curationReadService;
#MockBean
private BioSamplesAapService aapService;
private DocumentationHelper faker;
private MockMvc mockMvc;
#Before
public void setUp() {
this.faker = new DocumentationHelper();
this.mapper = new ObjectMapper();
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).uris()
.withScheme("https")
.withHost("www.myhost.com")
.withPort(443)
)
.build();
}
/**
* Generate the snippets for the API root
* #throws Exception
*/
#Test
public void getIndex() throws Exception {
this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk())
.andDo(document("get-index", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())));
}
/* Bunch of other similar tests */
}

I was able to solve my issue using an embedded mongodb instance.
For my specific needs this was sufficient to solve my issues with autoconfiguration.
In my pom I've added a dependence to de.flapdoodle.embed.mongo
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
and add a plugin to start/stop the embedded mongodb before/after mvn build
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<version>0.3.5</version>
<executions>
<execution>
<id>start</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

Related

Using #DataJpaTest in Spring Boot 3.0.0 Integration test causes Test discovery error

Whenever I add #DataJpaTest to a test test execution fails with the following error:
import com.owino.paginateddata.entities.Tweet;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit.jupiter.SpringExtension;
#DataJpaTest
#ExtendWith(SpringExtension.class)
public class PersistTweetTest {
#Autowired
private TestEntityManager entityManager;
#Test
public void shouldPersistTweetTest(){
var entity = entityManager.persistAndFlush(new Tweet(1L,"#goodvibes #sweetypie", "2022-12-11","11:00PM"));
Assertions.assertThat(entity).isNotNull();
Assertions.assertThat(entity.getId()).isEqualTo(1L);
Assertions.assertThat(entity.getContents()).isEqualTo("#goodvibes #sweetypie");
Assertions.assertThat(entity.getDateString()).isEqualTo("2022-12-11");
Assertions.assertThat(entity.getTimeString()).isEqualTo("11:00PM");
}
}
Internal Error occurred.
org.junit.platform.commons.JUnitException: TestEngine with ID 'junit-jupiter' failed to discover tests
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:160)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'com.owino.paginateddata.persistence_test.PersistTweetTest'] resolution failed
at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:103)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:46)
at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
... 13 more
Tests that are not annoted with #DataJpaTest and #ExtendWith(SpringExtension.class) execute smoothly. I have observed this only in Spring Boot 3.0.0, I am running these tests smoothly on 2.7.x.
While Running $ mvn test I noticed maven skips the test.
Running on Intelij 2022.3 leads to the above error being produced.

spring-boot upgrade to 2.3.1.RELEASE from 2.2.1.RELEASE (got failing tests.)

while upgrading from spring 2.1.2.RELEASE to 2.3.1.RELEASE was facing issues,
the gist of the complete configuration is.
added
<spring-boot.version>
2.3.1.RELEASE
</spring-boot.version>
and
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-validation
</artifactId>
</dependency>
keeping the rest of the versions and configs same.
cucumber version -3.0.2
Junit version - 4.12
so after change if we try to run the tests they fail.
we are calling repository's deleteAll() method when we see these exceptions in the logs, and if we comment the saveAndFlush() method we dont see exceptions.
though this issue is not due to cucumber it seems after some narrowing down that
Appreciate the help also if more info is needed on my specific case I can add details on suggestions.
the code sample is:
FooRepository.java:
package com.foo.respositories;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.foo.entities.FooEntity;
#Transactional
#Repository
public interface FooRepository extends JpaRepository<FooEntity, LocalDate> {
#Modifying
default void create(FooEntity entity) {
this.saveAndFlush(entity);
}
}
FooEntity.java:
package com.foo.entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import org.hibernate.envers.Audited;
#Entity
#Audited
#Data
public class FooEntity {
#Id
private LocalDate date;
private BigDecimal rate;
}
the trace of the log is as below.
org.springframework.dao.InvalidDataAccessApiUsageException: id to load is required for loading; nested exception is java.lang.IllegalArgumentException: id to load is required for loading
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible (AbstractEntityManagerFactoryBean.java :528)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy282.deleteAll(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 ( NativeMethodAccessImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
at com.sun.proxy.$Proxy158.deleteAll(Unknown Source)
at *.we clear out database
Caused by: java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.spi.LoadEvent.<init> (LoadEvent.java:96)
at org.hibernate.event.spi.LoadEvent.<init> (LoadEvent.java:64)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2781)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.lambda$load$1 (SessionImpl.java:2765)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.perform(SessionImpl.java:2721)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2765)

java.lang.ClassNotFoundException: org.apache.kafka.clients.consumer.ConsumerGroupMetadata

I am trying to create a simple Kafka producer. I followed a tutorial since I am new to this topic. I created a config file as recommended in the video. Here is the config file I am using.
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.support.serializer.JsonSerializer;
import java.util.HashMap;
import java.util.Map;
#Configuration
public class KafkaProducerConfig {
#Bean
public ProducerFactory<String, KafkaProducerModel> producerFactory() {
Map<String, Object> config = new HashMap<>();
config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:9092");
config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(config);
}
#Bean
public KafkaTemplate<String, KafkaProducerModel> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}
I am getting the following error when I try to run my application.
Caused by: java.lang.ClassNotFoundException: org.apache.kafka.clients.consumer.ConsumerGroupMetadata
at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[?:?]
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
at java.lang.Class.getDeclaredMethods0(Native Method) ~[?:?]
at java.lang.Class.privateGetDeclaredMethods(Class.java:3166) ~[?:?]
at java.lang.Class.getDeclaredMethods(Class.java:2309) ~[?:?]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:438) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:409) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:336) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1094) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
... 15 more
Its a gradle project and here is the dependency
implementation 'org.springframework.kafka:spring-kafka:2.5.6.RELEASE'
I did add the dependency after reviewing a stackover flow thread. However it did not resolve the error. Any lead would be helpful.
implementation 'org.apache.tomcat.embed:tomcat-embed-core'
You appear to have the wrong version of kafka-clients on the classpath. spring-kafka 2.5.6 uses kafka-clients 2.5.1. You should not declare the version yourself, Spring Boot will pull in the correct version.
Spring Boot 2.3.4 will pull in this version of spring-kafka and its dependencies. If you are using an older boot, you need to override all the dependencies.

Failing JUnit tests for embedded Fongo DB

I have a Spring Boot application which use MongoDB. I would like to use the embedded FongoDB for my JUnit tests. I follow some articles, for example:
http://dontpanic.42.nl/2015/02/in-memory-mongodb-for-unit-and.html
My Fongo test configuration looks like
package com.myproject.rest;
import com.github.fakemongo.Fongo;
import com.mongodb.Mongo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
#Profile("test")
#ComponentScan(basePackages = "com.myproject.service.data")
#EnableMongoRepositories(basePackages = "com.myproject.service.data.repository")
#Configuration
public class MongoTestConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "demo-test";
}
#Bean
#Override
public Mongo mongo() {
return new Fongo("mongo-test").getMongo();
}
}
I have this dependency for that:
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
I would like to test my services which autowired a repository interface which extends MongoRepository
package com.myproject.service.data.repository;
import com.myproject.service.data.entity.JournalData;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface JournalRepository extends MongoRepository<JournalData, String> {
#Override
public List<JournalData> findAll(Iterable<String> ids);
}
My tests class are inherited from the class below:
package com.myproject.rest;
import com.lordofthejars.nosqlunit.mongodb.MongoDbRule;
import cz.csas.services.commons.api.RequestMetadata;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
#PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", "javax.management.*", "javax.net.ssl.*"})
#PrepareForTest({RequestMetadata.class})
#ActiveProfiles("test")
public class EndpointTestContext {
#Autowired
protected MockMvc mockMvc;
//#Rule
//public MongoDbRule mongoDbRule = newMongoDbRule().defaultSpringMongoDb("demo-test");
#Before
public void setup() {
mockStatic(RequestMetadata.class);
when(RequestMetadata.builder()).thenCallRealMethod();
RequestMetadata m = RequestMetadata.builder()
.workingMode("TEST")
.build();
when(RequestMetadata.getMetadata()).thenReturn(m);
}
}
But when I run the Maven tests I recieve the following:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.mongodb.MongoClientOptions
at com.mongodb.MockMongoClient.create(MockMongoClient.java:42)
at com.github.fakemongo.Fongo.createMongo(Fongo.java:175)
at com.github.fakemongo.Fongo.<init>(Fongo.java:88)
at com.github.fakemongo.Fongo.<init>(Fongo.java:75)
at com.github.fakemongo.Fongo.<init>(Fongo.java:67)
at com.myproject.rest.MongoTestConfig.mongo(MongoTestConfig.java:30)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4.CGLIB$mongo$1(<generated>)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4$$FastClassBySpringCGLIB$$3ab8bfd7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4.mongo(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 115 common frames omitted
Can anyone suggest how to fix it? Thank you in advance.
Fongo can't find class from mongo-java-driver artifact. It declares
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.2</version>
</dependency>
as provided dependency. You should have mongo-java-driver on your test classpath. Most probably
<scope>runtime</scope>
or test will be enough for you.
Check if you have multiple version of mongo java driver (version conflicts). To check this, you can use mvn dependency tree to trace the path from where each jar is coming to your project.
mvn dependency:tree
Just need to find out the right version on mongo java driver and make sure you are not having version conflicts. I have used spring data and used fongo to write in-memory test case for mongodb queries.
<fongo-version>1.6.3</fongo-version>
<spring-data-mongodb-version>1.7.2.RELEASE</spring-data-mongodb-version>
<spring-framework-version>4.1.5.RELEASE</spring-framework-version>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring-data-mongodb-version}</version>
</dependency>
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>${fongo-version}</version>
<scope>test</scope>
</dependency>
Version conflict can come from may source (can confirm using above mvc dependency:tree command, one such source is mongobee, so if you are using it, please exclude mongo-java-drive by using exclusion
<dependency>
<groupId>com.github.mongobee</groupId>
<artifactId>mongobee</artifactId>
<version>${mongobee-version}</version>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</exclusion>
</exclusions>
</dependency>

Arquillan InvalidEnvironnmentException, suggests to add an already added plugin to Maven pom.xml

I configured my project and wrote my test class for a multi-module project. A test for a business service call to an AS400 server is written with Arquillan, which gives me an InvalidEnvironnmentException when I run the test.
package com.my.company.theproject.business.service.protect;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.my.company.theproject.common.dataaccess.PojoService;
import com.my.company.theproject.ServiceContext;
#RunWith(Arquillian.class)
public class SampleServiceTest
{
#Inject
#PojoService
SampleService service;
private ServiceContext context;
#Before
public void setUp()
throws Exception
{
context = new ServiceContext();
}
#Deployment
public static WebArchive createDeployment()
{
return ShrinkWrap
.create(WebArchive.class)
.addClasses(SampleService.class)
.addAsWebInfResource("META-INF/beans.xml", ArchivePaths.create("beans.xml"))
.addAsLibraries(
Maven.configureResolverViaPlugin().importRuntimeDependencies().resolve().withTransitivity().asFile());
}
#Test
public void test()
{
List<String> list = new ArrayList<String>();
list.add("AAA");
service.getStoredProcedureParameters(context, list);
fail("To be implemented");
}
}
I have written down the imports here, in case some were wrong (e.g. javax.inject.Inject ?).
The problem here is that Arquillian gives me this error at test runtime (first exception of the stack trace) :
java.lang.RuntimeException: Could not invoke deployment method: public
static org.jboss.shrinkwrap.api.spec.WebArchive
com.sopra.banking.packbanque.business.service.protect.SampleServiceTest.createDeployment()
At the end of the stack trace, I see this :
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.arquillian.container.test.impl.client.deployment.AnnotationDeploymentScenarioGenerator.invoke(AnnotationDeploymentScenarioGenerator.java:177)
... 50 more
Caused by: org.jboss.shrinkwrap.resolver.api.maven.InvalidEnvironmentException: Configuration from environment requires that user has following properties set, however they were not detected in runtime environment:
maven.execution.pom-file
maven.execution.offline
maven.execution.user-settings
maven.execution.global-settings
maven.execution.active-profiles
You should enable ShrinkWrap Maven Resolver Plugin to get them set for you automatically if executing from Maven via adding following to your <build> section:
<plugin>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>propagate-execution-context</goal>
</goals>
</execution>
</executions>
</plugin>
at org.jboss.shrinkwrap.resolver.impl.maven.task.ConfigureSettingsFromPluginTask.execute(ConfigureSettingsFromPluginTask.java:71)
at org.jboss.shrinkwrap.resolver.impl.maven.ConfigurableMavenResolverSystemBaseImpl.configureViaPlugin(ConfigurableMavenResolverSystemBaseImpl.java:119)
at org.jboss.shrinkwrap.resolver.api.maven.Maven.configureResolverViaPlugin(Maven.java:77)
at org.jboss.shrinkwrap.resolver.api.maven.Maven.configureResolverViaPlugin(Maven.java:59)
at com.sopra.banking.packbanque.business.service.protect.SampleServiceTest.createDeployment(SampleServiceTest.java:74)
... 55 more
The problem is that this plugin declaration is already in my Maven pom.xml !
<build>
<plugins>
<plugin>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-maven-plugin</artifactId>
<version>2.2.0-beta-2</version>
<executions>
<execution>
<goals>
<goal>propagate-execution-context</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
What is the problem here ?
I think the problem could be that you need to load the pom file first and then resolve as of now it dosent know that whene to resolve the dependencies from..
I am not sure but you can try this... :)
You can find everything about shrikwrap resolver here :
https://github.com/shrinkwrap/resolver

Categories