Can't find #SpringBootApplication from JUnit test file - spring

I was following the guide here, https://spring.io/guides/gs/spring-boot/ - cloned the project, built with Gradle and tried to run...application ran fine. Then I changed some file structure as per my requirement and tried to run the unit test case given there, but getting this error -
Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
I only restructure the codes in there, and this is my current project structure -
/projectroot
- /src/main/java
-Application.java
-/controller
-MyController.java
-/util
-MyUtil.java
-/model
-MyModel.java
Now trying to run test case from
/src/test/java/controller/MyControllerTest.java
I have gone through this Stack Overflow link and understood that if I put my test folder under /src/main/java/ it may work. But if I do that test file doesn't compile and it also doesn't seem the right way to put application code along with test code. I know I'm missing something very fundamental.

The way you setup your test (using the whole spring boot context), I believe MyControllerTest.java needs to be at most at the same level as Application.java. Also, I notice Application.java is using default package, you should move it into a package, so that all your beans are below your Spring Boot main class:
/projectroot
- /src/main/java/com/example/project/
-Application.java
-/controller
-MyController.java
-/util
-MyUtil.java
-/model
-MyModel.java
- /src/test/java/com/example/project/
-MyControllerTest.java
Spring's documentation
How Spring Boot's context is resolved from a test:
The search algorithm works up from the package that contains the test
until it finds a #SpringBootApplication or #SpringBootConfiguration
annotated class. As long as you’ve structure your code in a sensible
way your main configuration is usually found.
About using the default package with Spring Boot:
When a class doesn’t include a package declaration it is considered to
be in the “default package”. The use of the “default package” is
generally discouraged, and should be avoided. It can cause particular
problems for Spring Boot applications that use #ComponentScan,
#EntityScan or #SpringBootApplication annotations, since every class
from every jar, will be read.
We recommend that you follow Java’s recommended package naming conventions and use a reversed domain name (for example, com.example.project).

Related

Can't cope with running Spring: trouble with candidate component class for jdbc

I have set a task for myself. So far it is just to start Spring.
Repository: https://github.com/Kifsif/reusable
Trace back: https://dpaste.com/CA9YZ4Q3M
The error seems to be localized in the phrase "candidate component class" for jdbc. But I don't seem to have mentioned any database so far. And I'm making my project's structure along the lines of pom.xml generated by Spring Boot initializr.
This is warning in output log:
** WARNING ** : Your ApplicationContext is unlikely to start due to a #ComponentScan of the default package.
Your MainApplication.java is in the default package (src/main/java/MainApplication).
Please create a new package (for example: scr/main/java/example and move your MainApplication into that package, then it works.

Why does the package matter for Spring RESTful controller classes

I have the Spring sample RESTful server running. If I add controller classes to the com.example.restservice package, they work. But if I put the same class in the package net.windward.RESTfulEngine.Controllers - they are not found.
I don't see any setting anywhere. What is limiting where these controllers need to be located?
Spring starts scanning the packages from the main package that your #SpringBootApplication class exists and all of its sub-packages.for your case you need to use #ComponentScan in order to scan external packages.
It could work if you would define both package patterns to scan for an example
<context:component-scan base-package="com.example, net.windward" />
Or in Java code would be like
#ComponentScan({"com.example","net.windward"})
But if you would want to have only one package pattern scanned, then you need to keep them in order for an example to start everything with com. and add rest of your packages.
What component scan does it starts from "com." or whatever you defined in your configuration and it goes into all subdirectories, but only subdirectories, it does not scan around it. So if you would like to scan com. and net. you need to define both of them so spring can go into both of their subdirectories.
But approaches would do the work.

#Value config injection failing

I am trying to run a spring JUnit test case using -
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:some.xml" })
The xml has bean defined along with in memory db details
<bean id="orderService" class="com.example.OrderServiceImpl">
<!-- set properties, etc. -->
</bean>
I am doing #Value injection inside the bean class OrderServiceImpl, but it does not happen while executing the test case but the same runs fine when I run the application. Can you please help ?
You need to add a PropertySourcesPlaceholderConfigurer or PropertyPlaceholderConfigurer to your test context. This SO question may give you a hint: Populating Spring #Value during Unit Test.
Check to see if a some.xml exists in both main and test trees. If it exists in both, the one in the test tree should override the one in the main branch.
Make sure the some.xml you are actually loading has a property-placeholder, such as
<context:property-placeholder location="classpath:some.properties"/>
I realize that there are more modern ways to manage properties, but this is simple and easy to specify for unit tests.
I find that multiple tests become very awkward with config files on the classpath, so I like to take advantage of a feature of the #ContextConfiguration that lets me create a dedicated minimal config for each test. The way it works is that for each test class, by convention, it can look for a config file in the same relative directory path as your test class package, and named after your test case. That way you can completely control the config and properties for each test case. You might try it--it can eliminate confusion caused by shared config files. To do it, remove the value in the#ContextConfiguration. Then, say you have a test case com.myCompany.SomeTest located in src/test/java/com/myCompany/. Create a file called SomeTest-context.xml in directory src/test/resources/com/myCompany and put the minimal config you need for that unit in the file. #ContextConfiguration will, by convention, find the config file of that name in that location and use it for your test. Although not part of the conventions I just spoke of, I put a properties file for each test in the same directory with just the properties I need for that test, named after the test case as well (e.g. SomeTest.properties). In your test case-specific context, add a property-placeholder line like this to get your test-specific properties:
<context:property-placeholder location="classpath:com/myCompany/SomeTest.properties"/>
At the top of your test case, you would put
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration // no parameters
public class FileEncryptionUtilsTest { ...
If you do that, you'll be able to inject beans and values to your heart's content, without worrying about side-effects of things being added to a shared context or dealing with errors arising from multiple context files with the same name.
The key advantage is that you are testing a unit here, not the integration represented by an application context file. If you share an application context file in your unit tests, you're testing the application context along with your bean, and that's more of an integration test goal, not a unit test need.

Generating CRUD with Appfuse Maven Plugin(AMP)

A few Days Ago I Used the Command mvn appfuse:gen to generate CRUD with the Appfuse. But it Generated the folllowing files/classes for a given class (say, Category):
1) Category-validation.xml
2) CategoryAction-validation.xml
3) CategoryAction.java
4) CategoryActionTest.java
5) CategoryForm.jsp
6) CategoryList.jsp
I Expected it will generate the CategoryDao/CategoryDaoHibernate or maybe CategoryManager/CategoryManagerImpl Classes at least !!! But I was wrong.
Instead, we have the following code in CategoryAction class:
private GenericManager categoryManager;
And this is in Contradiction with the appfuse's standard tutorial (See this Page)
Can anybody tells me how to generate the CategoryDao/CategoryDaoHibernate and CategoryManager/CategoryManagerImpl Classes for the project?
Use -Damp.genericCore=false when you run appfuse:gen. Like the following:
mvn appfuse:gen -Dentity=Category -Damp.genericCore=false
It's already explained in following post:
Stackoverflow: running “mvn appfuse:gen” does nothing
but basically, it's the same like previous post from Matt Raible
After running that command (for EVERY entity), you'll get:
DAO layer
DAO interfaces
DAO (Hibernate) implementation
Service layer
Manager interfaces
Manager implementations
Webapp layer
Controllers (if you are using SpringMVC framework)
JSP pages
and whole bunch of all other required resources (various Resource Bundle properties, Spring XML files, Menu configurations...). Of course, it's all based on your model, your defined JavaBean classes.
After that, you just need to put some extra code inside implementation classes if you need some customized functionalities, some additional business logic.
I hope it helps.

Play! Framework - Spring.getBeanOfType works but #Autowired fails

I am using play spring-1.0.1 module and as per the documentation :
To enable component scanning, add this line to the
/conf/application.conf file:
play.spring.component-scan=true
Note that enabling this scans for #org.springframework.stereotype.Component,
#org.springframework.stereotype.Repository,
#org.springframework.stereotype.Service
to identify Spring beans.
Additionally, running the component
scan enables support for annotation
based configuration (i.e.,
#org.springframework.beans.factory.annotation.Autowired,
etc).
When I try the same thing, it fails saying NullPointerException, since it is not able to wireup the beans to the corresponding class.
Although
play.modules.spring.Spring.getBeanOfType(UserManager.class);
just works fine on my models.
Is it a known issue or I am doing it incorrectly
Thank you

Resources