Reputation: 627
I have a Spring Boot REST service and some unit tests written for the data layer. I use the embedded MongoDB dependency to perform the basic CRUD tests for my Repository class:
public interface UserRepository extends MongoRepository<UserEntity, String> {
Optional<UserEntity> findByUsername(String username);
}
I load the data from a JSON file (located under test/java/resources/data) and with the help of an ObjectMapper
instance, I load the data into the embedded DB before each test and drop the collection after it's completed:
@DataMongoTest
class UserRepositoryTest {
// the path to the JSON file
private final File USER_DATA_JSON = Paths.get("src", "test", "resources", "data", "UserData.json").toFile();
// used to load a JSON file into a list of Users
private final ObjectMapper objectMapper = new ObjectMapper();
@Autowired
private MongoTemplate mongoTemplate; // makes the interaction with the embedded MongoDB much easier
@Autowired
private UserRepository userRepository;
@BeforeEach
void setUp() throws IOException {
// deserialize the JSON file to an array of users
UserEntity[] users = objectMapper.readValue(USER_DATA_JSON, UserEntity[].class);
// load each user into embedded MongoDB
Arrays.stream(users).forEach(mongoTemplate::save);
}
@AfterEach
void tearDown() {
// drop the users collection
mongoTemplate.dropCollection("users");
}
@Test
void testFindAllSuccess() {
// WHEN
List<UserEntity> users = userRepository.findAll();
// THEN
assertEquals(2, users.size(), "findAll() should return 2 users!");
}
// other test methods
}
In my local environment, everything works just fine, no configuration is needed inside the application.properties
file. But when I execute a build on Jenkins, the following error appears for all the Repository tests:
UserRepositoryTest > testFindAllSuccess() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:658
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:185
Caused by: java.net.UnknownHostException at InetAddress.java:1642
Caused by: java.net.UnknownHostException at Inet6AddressImpl.java:-2
The build.gradle
file dependencies are declared as follows:
implementation 'org.openapitools:openapi-generator-gradle-plugin:5.0.0'
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation "io.springfox:springfox-boot-starter:3.0.0"
implementation('org.modelmapper:modelmapper:2.3.0')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
testImplementation 'io.projectreactor:reactor-test'
compile 'io.springfox:springfox-swagger-ui:3.0.0'
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
compile 'org.mongodb:mongodb-driver-sync'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-test'
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
I assume Spring Boot is not identifying the embedded MongoDB anymore. How can I configure it as simple as possible?
I saw there is a possibility of using containerized MongoDB and test it using @TestContainers
, but for now I need to fix this issue since every build fails due to the tests.
LATER EDIT: By activating the --debug
option in Jenkins when running the build, I discovered the following cause:
java.net.UnknownHostException: dev096.dev.cloud.******.eu: dev096.dev.cloud.******.eu: Name or service not known
Do you know if I have to add that address to the known hosts to my local machine (etc/hosts) or it should be configured locally with profiles (localhost
for development and dev096.dev.cloud.******.eu
for production)?
Upvotes: 4
Views: 1651
Reputation: 627
Unfortunately, none of your solutions worked for me, but I found out later that dev096.dev.cloud.******.eu
is the Jenkins instance itself.
The fix was to add an entry in /etc/hosts/
such that the server's IP to be also recognized as dev096.dev.cloud.******.eu
Upvotes: 1
Reputation: 861
I managed to reproduce the same error locally and, if you haven't solved it yet, this is my take.
Remove all MongoDB custom configurations/properties, then add the following class to your project:
@Configuration
public class MongoTestConfig {
@Bean
MongoProperties properties() {
MongoProperties mongoProperties = new MongoProperties();
mongoProperties.setPort(33333);
mongoProperties.setHost("localhost");
return mongoProperties;
}
}
Make sure you tag your test class (UserRepositoryTest) with these three annotations:
@RunWith(SpringRunner.class)
@DataMongoTest
@Import(MongoTestConfig.class)
@DataMongoTest ignores all other bean definitions so we force the test to include the configuration that we just created using the explicit @Import.
Now the test will be forced to run on localhost. Hope it's going to work for you as it did for me! 😁
Upvotes: 3
Reputation: 3264
If dev096.dev.cloud.******.eu
is a host used only in production, then your production server needs to know that host; not your local PC, nor Jenkins.
Ideally, you'd run your Jenkins tests using a 'jenkins' Spring profile, and then define the localhost
in application-jenkins.properties.
Upvotes: 2