Getting spring application variables into Integration Tests - spring

I've set up integration tests for testing my API and I want my tests to pick up settings from application.yml. The trouble is that my test class never reads the value of ${base-urls.test-url} from the properties file. I've tried using #ContextConfiguration, #TestPropertySource, #PropertySource and #RunWith(SpringRunner.class) without success.
How can I get my integration test to read the properties file?
My project directories look like this:
|____src
| |____test
| | |____resources
| | |____java
| | | |____org
| | | | |____example
| | | | | |____forex
| | | | | | |____controller
| | | | | | | |____CurrencyControllerTest.java
| | | | | | |____service
| | | | | | | |____CurrencyServiceTest.java
| |____integrationTest
| | |____resources
| | | |____application.yml
| | |____java
| | | |____org
| | | | |____example
| | | | | |____forex
| | | | | | |____integration
| | | | | | | |____ApiTests.java
| | | | | | |____domain
| | | | | | | |____CurrencyHelper.java
| |____main
| | |____resources
| | | |____application.yml
| | |____java
| | | |____org
| | | | |____example
| | | | | |____Application.java
| | | | | |____forex
| | | | | | |____repository
| | | | | | | |____CurrencyRepository.java
| | | | | | |____controller
| | | | | | | |____CurrencyController.java
| | | | | | |____service
| | | | | | | |____CurrencyService.java
| | | | | | |____domain
| | | | | | | |____Currency.java
I have an application resource file, src/integrationTest/resources/application.yml and also tried placing it in the same package as ApiTests class. The file contains this:
base-urls:
test-url: ${TEST_URL:http://localhost:8080}
The set up is that I want to have a running application, then run my integration tests with the URL from the #Value annotation. My test class uses Rest Assured and looks like this:
public class ApiTests {
#Value("${base-urls.test-url}")
private String baseUrl;
private Currency dummy;
#Before
public void setup() {
RestAssured.baseURI = baseUrl;
dummy = CurrencyHelper.dummy();
}
My build.gradle file looks like this:
plugins {
id 'java'
id 'application'
id 'io.spring.dependency-management' version '1.0.7.RELEASE'
id 'org.springframework.boot' version '2.3.4.RELEASE'
}
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'
group 'org.example.forex'
version '1.0-SNAPSHOT'
sourceCompatibility = '1.8'
mainClassName = 'org.example.Application'
sourceSets {
integrationTest {
resources {
srcDir 'src/integrationTest/resources'
}
compileClasspath += sourceSets.main.output + configurations.testRuntime
runtimeClasspath += output + compileClasspath
}
}
def versions = [
postgresql : '42.2.2'
]
repositories {
mavenCentral()
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter"
implementation "org.springframework.boot:spring-boot-starter-web"
implementation'org.springframework.boot:spring-boot-starter-data-jpa'
implementation "org.postgresql:postgresql:${versions.postgresql}"
testImplementation "org.springframework.boot:spring-boot-starter-test"
testImplementation group: 'junit', name: 'junit', version: '4.12'
integrationTestImplementation "org.springframework.boot:spring-boot-starter-test"
integrationTestImplementation "org.springframework:spring-test"
integrationTestImplementation 'io.rest-assured:rest-assured:3.3.0'
integrationTestImplementation "com.fasterxml.jackson.core:jackson-databind:2.11.0"
integrationTestImplementation 'junit:junit:4.12'
}
task integrationTest(type: Test) {
description = 'Runs integration tests.'
group = 'verification'
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}

I believe what you're looking for is the SpringBootTest annotation. Add the following annotation atop your test class.
#RunWith(SpringRunner.class)
#SpringBootTest
Should you need, you can pass additional properties into the Spring environment by including them in your SpringBootTest annotation, as in
#SpringBootTest(properties = "com.mycompany.myclass.someproperty=some_value")
If the properties you're trying to load are in a profile specific property file, you can activate that profile with
#ActiveProfiles(value = "my_profile")

Okay. Thanks to #lane.maxwell for the clue, I figured out the missing dependency.
These do work as #lane.maxwell says:
#RunWith(SpringRunner.class)
#SpringBootTest
Basically, my app uses a database and I need to to add the DB dependencies to build.gradle for the integration tests to work:
integrationTestImplementation'org.springframework.boot:spring-boot-starter-data-jpa'
integrationTestImplementation "org.postgresql:postgresql:${versions.postgresql}"

Related

ansible inventory variable precedence and levels

FL - Florida,
CA - California,
US - United States
hosts.ini:
############
### CORE ###
############
[SERVERS_FL_0102]
server01-FL
server02-FL
[SERVERS_FL_0304]
server03-FL
server04-FL
[SERVERS_CA_0102]
server01-CA
server02-CA
[SERVERS_CA_0304]
server03-CA
server04-CA
############
## GROUPS ##
############
[SERVERS_FL:children]
SERVERS_FL_0102
SERVERS_FL_0304
[SERVERS_CA:children]
SERVERS_CA_0102
SERVERS_CA_0304
[SERVERS_US_0102:children]
SERVERS_FL_0102
SERVERS_CA_0102
[SERVERS_US_0304:children]
SERVERS_FL_0304
SERVERS_CA_0304
[SERVERS_US:children]
SERVERS_FL
SERVERS_CA
My question to you is: does SERVERS_US_0304 group vars file have greater precedence than SERVERS_US group vars file? For me it is difficult to say, as SERVERS_US_0304 is not inside SERVERS_US. My guess is that SERVERS_US_0304 does have greater precedence than SERVERS_US as it contains fewer groups, so it is smaller. I don't know for sure.
My question to you is: does SERVERS_US_0304 group vars file have greater precedence than SERVERS_US group vars file?
You may have a look into Understanding variable precedence and the output of
ansible-inventory -i inventory.ini --graph
#all:
|--#SERVERS_US:
| |--#SERVERS_CA:
| | |--#SERVERS_CA_0102:
| | | |--server01-CA
| | | |--server02-CA
| | |--#SERVERS_CA_0304:
| | | |--server03-CA
| | | |--server04-CA
| |--#SERVERS_FL:
| | |--#SERVERS_FL_0102:
| | | |--server01-FL
| | | |--server02-FL
| | |--#SERVERS_FL_0304:
| | | |--server03-FL
| | | |--server04-FL
|--#SERVERS_US_0102:
| |--#SERVERS_CA_0102:
| | |--server01-CA
| | |--server02-CA
| |--#SERVERS_FL_0102:
| | |--server01-FL
| | |--server02-FL
|--#SERVERS_US_0304:
| |--#SERVERS_CA_0304:
| | |--server03-CA
| | |--server04-CA
| |--#SERVERS_FL_0304:
| | |--server03-FL
| | |--server04-FL
|--#ungrouped:
... the last listed variables override all other variables ...
... Ansible gives precedence to variables that were defined more recently, more actively, and with more explicit scope. ...
If you apply tasks on the group SERVERS_US, the group var file of SERVERS_US_0304 will not be read since it is not part of the (sub)tree.
ansible-inventory -i inventory.ini SERVERS_US --graph
#SERVERS_US:
|--#SERVERS_CA:
| |--#SERVERS_CA_0102:
| | |--server01-CA
| | |--server02-CA
| |--#SERVERS_CA_0304:
| | |--server03-CA
| | |--server04-CA
|--#SERVERS_FL:
| |--#SERVERS_FL_0102:
| | |--server01-FL
| | |--server02-FL
| |--#SERVERS_FL_0304:
| | |--server03-FL
| | |--server04-FL
And so vice versa.
ansible-inventory -i inventory.ini SERVERS_US_0304 --graph
#SERVERS_US_0304:
|--#SERVERS_CA_0304:
| |--server03-CA
| |--server04-CA
|--#SERVERS_FL_0304:
| |--server03-FL
| |--server04-FL
Therefore it will somehow depend on what you try to achieve. How to build your inventory gives some examples for organizing and grouping, as well the answer about ansible_group_priority.

Completely remove log4j

I have a brand new test project from start.spring.io, with the following gradle file:
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
When looking at dependencies, I get the following:
| | +--- org.springframework.boot:spring-boot-starter-logging:2.6.2
| | | +--- ch.qos.logback:logback-classic:1.2.9
| | | | +--- ch.qos.logback:logback-core:1.2.9
| | | | \--- org.slf4j:slf4j-api:1.7.32
| | | +--- org.apache.logging.log4j:log4j-to-slf4j:2.17.0
| | | | +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.32
| | | | \--- org.apache.logging.log4j:log4j-api:2.17.0
| | | \--- org.slf4j:jul-to-slf4j:1.7.32
| | | \--- org.slf4j:slf4j-api:1.7.32
How can I completely remove log4j from the project and what should my gradle file look like? I would like to use logback exclusively.
You're already free of log4j.
If your dependencies don't include the log4j core jar, then you're not logging to log4j. The api jar doesn't have any functionality. The api jar together with the log4j-to-slf4j jar make sure that any dependency that is written to use log4j directly has its logging redirected to slf4j, which will use logback.

Laravel - How to run schedule in multiple packages

currently, i'm working with project that has some modules which need to run schedule job.
I want to take schedule job into Kernel of each module (not Kernel in app/Console directory).
I did like this Laravel 5 Package Scheduled Tasks but it only run on 1 module. The others did not run.
Can anybody please help me! Thanks
My source code has structure like this:
app
| Console
| | Commands
| | | Command.php
| | Kernel.php
bootstrap
...
Module
| Module 1
| | Console
| | | Commands
| | | | Command11.php
| | | | Command12.php
| | | Kernel.php
| Module 2
| | Console
| | | Commands
| | | | Command21.php
| | | | Command22.php
| | | Kernel.php

Laravel - Pivot table - No join throws an error

I've a question regarding how Laravel handles pivot tables:
Summarizing: 2 models, Project and Stage.
Project
+----+----------+
| id | name |
+----+----------+
| 1 | Project1 |
| 2 | Project2 |
+----+----------+
Stage
+----+--------+
| id | name |
+----+--------+
| 1 | Stage1 |
| 2 | Stage2 |
| 3 | Stage3 |
+----+--------+
And a pivot table
+----+------------+----------+------------+-----------+
| id | project_id | stage_id | date | info |
+----+------------+----------+------------+-----------+
| 1 | 1 | 1 | 2014-12-20 | Moreinfo1 |
| 2 | 1 | 2 | 2014-12-21 | Moreinfo2 |
| 3 | 2 | 1 | 2014-12-22 | Moreinfo3 |
| 4 | 1 | 3 | 2014-12-23 | Moreinfo4 |
+----+------------+----------+------------+-----------+
I'm showing the info:
+----------+------------+------------+-----------+
| project | last_stage | date | info |
+----------+------------+------------+-----------+
| Project1 | 3 | 2014-12-23 | Moreinfo4 |
| Project2 | 1 | 2014-12-22 | Moreinfo3 |
+----------+------------+------------+-----------+
And everything works fine; however, if I add a new Project (as there's no info on the pivot table), I get the annoying:
Whoops, looks like something went wrong.
Is there any way to indicate that, in case of null, the row should be left empty (without an error)? I'd like to get:
+----------+------------+------------+-----------+
| project | last_stage | date | info |
+----------+------------+------------+-----------+
| Project1 | 3 | 2014-12-23 | Moreinfo4 |
| Project2 | 1 | 2014-12-22 | Moreinfo3 |
| Project3 | | | |
+----------+------------+------------+-----------+
The problem is the call in your view:
{{ $project->stages_accomp()->orderBy('date', 'desc')->first()->pivot->date }}
When you have a project that has no stage assigned ->first() will return null.
And PHP doesn't like it if you want to access a property of a non-object (in this case null)
You need to add a little check like this:
#if($stage = $project->stages_accomp()->orderBy('date', 'desc')->first())
{{ $stage->pivot->date }}
#endif
It will make sure the first() returns a truthy value (not null) and will also assign the value to the variable $stage.

<<Spring Boot 1.1.6>> Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException

I am new to spring boot and building an application with Spring boot 1.1.6.The basic application was working fine.
But when I added some dependencies, I am unable to start the application and seeing the below exception during staring.
My build.gradle file
` buildscript {
ext {
springBootVersion = '1.1.6.RELEASE'
}
repositories {
maven {
url "http://repo.spring.io/libs-snapshot"
}
mavenLocal()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
sourceCompatibility = 1.7
compileJava {
targetCompatibility = 1.7
}
war {
baseName = 'gs-convert-jar-to-war'
version = '0.1.0'
}
repositories {
mavenCentral()
mavenLocal()
maven { url "http://repo.spring.io/libs-snapshot" }
maven { url "http://maven.springframework.org/milestone" }
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") {
exclude module: "spring-boot-starter-tomcat"
exclude module:"spring-boot-starter-logging"
}
providedRuntime("org.springframework.boot:spring-boot-starter-jetty:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
compile("org.springframework.boot:spring-boot-starter-security:${springBootVersion}")
compile("com.google.guava:guava:17.0")
compile("com.squareup.retrofit:retrofit:1.6.0")
compile("commons-io:commons-io:2.4")
compile("com.local.abdd:abdd-jith912:1.0.4-SNAPSHOT"){
exclude module:"slf4j-api"
}
compile("com.local.abdd:abdd-jith912:1.0.4-SNAPSHOT:tests"){
exclude module:"slf4j-api"
}
testCompile("junit:junit")
compile("org.slf4j:slf4j-api:1.7.7"){
force = true
}
compile("org.slf4j:slf4j-log4j12:1.7.7"){
force=true
}
compile("org.slf4j:slf4j-jdk14:1.7.7"){
force=true
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
`
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Failed to load bean class: ; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:392)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:165)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:305)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at org.magnum.mobilecloud.video.Application.main(Application.java:27)
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/security/config/annotation/authentication/configurers/GlobalAuthenticationConfigurerAdapter.class] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
at org.springframework.core.type.classreading.SimpleMetadataReader.(SimpleMetadataReader.java:50)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:82)
at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:77)
at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:561)
at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getSuperClass(ConfigurationClassParser.java:736)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:284)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:218)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:435)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:258)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:218)
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:435)
at org.springframework.context.annotation.ConfigurationClassParser.processDeferredImportSelectors(ConfigurationClassParser.java:389)
... 13 more
My gradle dependencies output is too huge that I cannot enter here.
However I find some spring components used as transitive dependencies like
| +--- com.local.infra.thirdparty:oracle-simplefan:11.2.0.2
| | | | | | +--- javax.jms:jms:1.1
| | | | | | +--- org.springframework:spring-jms:3.1.1.RELEASE
| | | | | | | +--- aopalliance:aopalliance:1.0
| | | | | | | +--- org.springframework:spring-aop:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-beans:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-context:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework:spring-core:3.1.1.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | \--- org.springframework:spring-tx:3.1.1.RELEASE -> 3.2.2.RELEASE
| | | | | | | +--- aopalliance:aopalliance:1.0
| | | | | | | +--- org.springframework:spring-beans:3.2.2.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | \--- org.springframework:spring-core:3.2.2.RELEASE -> 4.0.7.RELEASE (*)
and
+--- org.springframework.security:spring-security-core:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | +--- org.springframework.security:spring-security-taglibs:3.0.4.RELEASE
| | | | | | | | +--- org.springframework.security:spring-security-web:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | | +--- org.springframework.security:spring-security-acl:3.0.4.RELEASE
| | | | | | | | | +--- org.springframework.security:spring-security-core:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
| | | | | | | | | \--- org.springframework:spring-context-support:3.0.3.RELEASE -> 3.2.2.RELEASE (*)
| | | | | | | | \--- org.springframework:spring-web:3.0.3.RELEASE -> 4.0.7.RELEASE (*)
| | | | | | | +--- org.springframework.security:spring-security-config:3.0.4.RELEASE -> 3.2.5.RELEASE (*)
I'm not 100% sure that this will solve your problem, but it will move things in the right direction.
You have a number of dependencies that are out of sync with other dependencies from the same Spring project. For example you have a mix of versions in your Spring Framework dependencies. Most are 4.0.7.RELEASE but a few are 3.x.x.
One way to fix this is to add an explicit, direct dependency on the problematic modules (Spring Boot will provide the right version for you. For example:
dependencies {
compile 'org.springframework:spring-context-support'
compile 'org.springframework:spring-jms'
compile 'org.springframework:spring-tx'
compile 'org.springframework:spring-security-acl'
compile 'org.springframework:spring-security-taglibs'
}
Try making this change and looking at the output of gradle dependencies again. Repeat the process if you spot any other modules with versions that are out of line with their other modules in the same Spring project. Once the versions all look right, try running your app again.

Resources