Spring MVC unit test. Spring Boot Application eads wrong configuration - java

I have some problem with configuration my unit test. I have mock-test class configuration:
#TestConfiguration
public class TestContext {
#Bean
// #Qualifier("userTestServiceImplWithMongoDB")
public UserService userService() {
return Mockito.mock(UserService.class, "userServiceImplWithMongoDB");
}
#Bean
// #Qualifier("taskTestServiceImplWithMongoDB")
public TaskService taskService() {
return Mockito.mock(TaskService.class, "taskServiceImplWithMongoDB");
}
}
This file is in src/test/java directory. I start my application with class:
#SpringBootApplication
#Configuration
#EnableMongoRepositories
#ComponentScan
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
My problem is that application starts with wrong configuration - this one from my test config class.
I use MongoDB repositories and I have service layer using thats repositories.
I followed this instructions: Some tutorial.
I am new to Spring, do you know what I can do to fox it?
Have a nice day :)

The tutorial you are following is not for spring, not spring-boot. It is still a good tutorial to use MockMvc, however it does not cover how to load the context through spring-boot.
Check this to setup a unit test with Spring-Boot: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class YourTest {
...
}

Related

Getting error to connect database after using #Component

Using #Component annotation in Spring Cron, cron is running well, but another configuration is not working, like database connection is not established, loggers are not printing
Getting error while login from the web project
Below is my code
#org.springframework.boot.autoconfigure.SpringBootApplication
#ComponentScan(basePackages= {"com.ravi","com.ravi.main"})
#EnableScheduling
public class SpringBootApplication extends SpringBootServletInitializer{
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringBootApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication.class, args);
}
}
And below code is cron
#Component
#Lazy(false)
public class CleanDataJob {
private static Logger logger = Logger.getLogger(CleanDataJob.class);
#Scheduled
public void deleteData() {
// Cleaning data job code
}
}
Cron is added in com.ravi.main package
After deleting #Component all database connections are working fine but, cron is not running
Check for #Autowired annotation that is left inside the #Component annotated class

Spring AOP adviced methods do not work. My configuration seems ok

I'm trying to create a demo AOP application but it just does not work right.
I read through all tutorials and got it working with #RestController but as I tried it with a plain java spring driven application I just can't get it to work. Please review my files and tell me where my mistake lies in.
Application Class
#SpringBootApplication
#ComponentScan("com.xetra.experimental")
#EnableAspectJAutoProxy
public class AoptryoutnowebApplication {
public static void main(String[] args) {
SpringApplication.run(AoptryoutnowebApplication.class, args);
DefaultClassToAspectImpl defaultClassToAspectImpl = new DefaultClassToAspectImpl();
defaultClassToAspectImpl.doStuff();
}
}
ClassToAspect Interface
public interface ClassToAspect {
void doStuff();
}
ClassToAspect Implementation
#Component
public class DefaultClassToAspectImpl implements ClassToAspect {
#FooAnnotation
public void doStuff(){
System.out.println("DoStuff!");
}
}
Annotation for Pointcut
public #interface FooAnnotation {
}
Aspect Class
#Aspect
public class FooAspect {
#Pointcut("#annotation(FooAnnotation)")
public void methods(){
}
#Before("methods()")
public void doAspect(){
System.out.println("FooAspect before");
}
}
Try this:
replace #EnableAspectJAutoProxy with #EnableAspectJAutoProxy(proxyTargetClass = false)
change pointcut to
#Pointcut("execution (* your.package..*.*(..)) && #annotation(fooAnnotation))")
The problem is you are using a non Spring managed instance by doing new DefaultClassToAspectImpl(). Spring AOP only works for Spring managed beans, because by default Spring AOP is proxy based.
So instead of doing new DefaultClassToAspectImpl() you should be obtaining the instance from the ApplicationContext. When using Spring Boot the SpringApplication.run call returns an ApplicationContext. Here you can use one of the getBean methods to obtain the instance you want.
ApplicationContext ctx = SpringApplication.run(AoptryoutnowebApplication.class, args);
ClassToAspect bean = getBean(ClassToAspect.class);
bean.doStuff();
This way you get the Spring managed

How the Spring boot works with DispatcherServlet to call the correct mapped api with jersey

I am using Spring boot with jersey. Here, I extend SpringBootServletInitializer with my Application class
#SpringBootApplication
#ComponentScan({"com.pqr.configuration", "com.pqr.other"})
class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApplication .class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication .class);
}
}
/*jersey config class*/
#Configuration
#ApplicationPath("/rest")
class JerseyConfig extends org.glassfish.jersey.server.ResourceConfig{
public JerseyConfig() {
packages("com.pqr.service");
}
}
I want to understand how the controller communicates with DispatcherServlet here and url are handled? If there is another flow, please mention. There are many concepts involved like Restcontrollers, InternalViewResolver, UrlHandler etc. I need to know what exactly happens in background?

Spring Boot: Is it safe to pass many Instances for CommandLineRunner

I'm a bit new to Spring Boot. I have an Application.java class where I have some code:
#SpringBootApplication(exclude = JpaRepositoriesAutoConfiguration.class)
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
...
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner App(DBReportRepository dbReportRepository,
ClientRepository clientRepository, FileParser fileParser,
MessagingService messagingService, ClientReportFactoryImpl clientReportFactory) ...
I was wondering is it a good practice to pass so many parameters (which are #Services annotated classes) to CommandLineRunner.
Or am I making Spring Boot do too much and there is another way to make Spring Boot be aware of those #Services classes.
Turned out my spring boot configuration was missing an AppConfig class. Without it I could only use #Autowired with #Component classes or #Service classes which were passed as arguments to CommandLineRunner. I created the AppConfig.java looking like this:
#Configuration
#ComponentScan(basePackages = "your.main.package")
public class AppConfig {
}
And after that I could use the #Autowired everywhere possible.

Combine 2 Spring boot application

Just following Spring Guides http://spring.io/guides#gs I took gs-rest-service and gs-accessing-data-jpa. Now I want to combine them in one application, and that is where like more understanding of new org.springframework.boot.SpringApplication is needed.
In gs-rest-service config looks emazing, that is almost absent
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
gs-accessing-data-jpa is more like Spring XML JavaConfig based app.
#Configuration
#EnableJpaRepositories
public class CopyOfApplication {
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(H2).build();
}
// 2 other beans...
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(CopyOfApplication.class);
CustomerRepository repository = context.getBean(CustomerRepository.class);
//...
}
}
How to combine them?
Does it mean that I need to re-write SpringApplication.run now on more detailed level ?
In the Spring Boot application simply add the dependencies from the JPA sample (the ones which you don't already have.
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M7")
compile("org.springframework:spring-orm:4.0.0.RC1")
compile("org.springframework.data:spring-data-jpa:1.4.1.RELEASE")
compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
compile("com.h2database:h2:1.3.172")
testCompile("junit:junit:4.11")
}
or instead of this you could also use the spring boot starter project for Spring Data JPA. In that case the dependencies would look like the following.
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:0.5.0.M7")
compile("org.springframework.boot:spring-boot-starter-data-jpa:0.5.0.M7")
compile("com.h2database:h2:1.3.172")
testCompile("junit:junit:4.11")
}
This will pull in all needed dependencies.
Next copy the CustomerRepository to the Spring Boot application. That basically should be everything you need. Spring Boot auto-configure now detects Spring Data JPA and JPA and will bootstrap hibernate, spring data for you.
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
ApplicationContext context= SpringApplication.run(Application.class, args);
CustomerRepository repository = context.getBean(CustomerRepository.class);
//...
}
}

Categories

Resources