Automatic, contained testing of a web app - spring

I have a web application that uses Spring, Jersey (for REST) and Hibernate+PostgreSQL. I'm using REST Assured for the testing framework. I created a simple test case and it works as long as I run Tomcat with my war.
I have a few questions regarding isolation & automatic tests:
I don't want to run tomcat just for the test. I would like to embed an app server.
I want to isolate my DB calls so that I can test it in a clean, predictable way.
Any suggestions, tips, links etc. for these challenges will be awesome.

You could use embedded Jetty as an embedded application server. Check out this and this post for details.
What you most likely want in this case is to run the application with a Spring profile,
in which profile the only thing that changes is the datasource. You would likely want to use an in-memory database like H2 or HSQL. Chek out this and this post.

Related

How to deploy Spring Boot MVC project for others to see?

I've made a spring boot project called student-management using spring MVC, Thymeleaf, spring data JPA and MySql. When I run it locally on localhost:8081 it works perfectly. I made CRUD operations so I see all the changes in database when changed on the website and vice versa.
Now, I need to get my website "out there" for others to see, specifically a company. I'm new to Spring boot and everything that goes with it but I don't understand how to deploy my rather simple website so the company can access it by not using localhost.
This is my project_hierarchy. As you can see it's quite simple.
This is my StudentController.java. I've used #Controller and maybe I should've used #RestController. If so, how do I change it to #RestController so that my website still works.
My thymeleaf html files students.html edit_students.html create_student.html
Deploying remotely means choosing a host (e.g. AWS), setting up infrastructure, deploying your executable JAR with dependencies, and running it on a server.
You'll need to set up a separate MySQL instance and connect your app to it. That means you'll set up the database server, create the database and schema, and start it up before your app starts.
You should be thinking about security and who should be able to access your app and data. Most developers who have only deployed locally tend to put off those considerations. I'd urge you to think about them sooner.
If your purpose is to provide access inside your company, only to employees, perhaps you'd be better off making your local machine available to others on the network OR choose a server that's already on your company network. You'll have to work with others to make that happen.

Start a springboot project for each test case

We are developing test cases for a micro service using Spring Boot. One of the requirement is that for each Junit test case we need to:
start the project
test a unit case and
then stop the project .
I feel this is an anti pattern, but this is the requirement.
I looked around internet but couldn't find a solution for the same. I was able to start a web server but it provided no response and this might be because the project is not assigned to the server.
Does anyone have any idea on how this can be achieved?
PS: We don't want to use Mockito
Before hand i want to make clear that this a very bad practice and should be avoided. This approach does not implement unit tests concept correctly because you are testing an entire system up, so JUnit wouldn't be the correct tool.
I pocked around and i don't seem to find a Runner that may be able to do this (does not surprise me although), the most similar Runner may be SpringJUnit4ClassRunner which provides you a complete Spring context in your test space, but won't go live with the application.
An approach i'd suggest if you really want to go with this is to use tools like REST Assured to do End-to-End API layer tests against the live application, but this implies that you have to find another way to start the app, and then point the REST Assured tests to that started app. Maybe a shell script that starts the app and then starts the REST Assured tests suits, then when the suit ends put down the server.
I highly suggest you to chat with your product/management teams to avoid this kind of stuff since the tests will take FOREVER to run and you will be polluting your local or remote DBs if you are persisting data or other systems through REST or SOAP calls.

Starting embedded servers before context loads in Spring Boot for testing

I am working on a sample application right now using Spring Boot, Spring Data JPA, and Spring Data Elasticsearch. I want to be able to run the unit tests as part of a pipeline build, but they require Elasticsearch to be running to work as the service makes calls to said ES server. SQL works fine because I am using an in-memory H2 instance.
I have implemented some code to attempt to launch ES as an "embedded" server. The embedded server works just fine, but it seems like, at least from what I can tell, it is started AFTER the context loads. Most importantly after the ElasticSearchConfiguration does it's thing.
I think I need refactor the code out of AbstractElasticsearchTest into a separate class that can run prior to ElasticSearchConfiguration generates the client/template, but I am not sure how to do it, nor how to Google said process.
Is there some mechanism in Spring Boot that could be used to start the embedded servers prior to running any of the configurations? Or is there some way I could enhance ElasticSearchConfiguration to do it prior to creating the client/template, but only when running the unit tests?
Edit:
So, just to be a little more specific...what I am looking for is a means/way to either run ES 5 in "embedded" mode OR how to mock up the Spring Data ES code enough so that it works for the CI server. The code linked above currently is mixing unit tests with integration tests, I know, as it's currently making calls to a physical ES server. That's what I am trying to correct: I should be able to stub/mock enough of the underlying Spring Data code to make the unit test think it's talking to the real-deal. I can then change the tests that determine if the documents made it to ES and test things like type-ahead searches to be integration tests instead so they do not run when CI or Sonar runs.
Ok, so for those that might come back here in the future, this commit shows the changes I made to get ES to run as "embedded".
The nuts-and-bolts of it was to start the node as "local" then physically return node.client(). Then in the Spring Bean method that gets the client, check if you have "embedded" turned on, if so start the node and return it's Client (the local one), if not just build the client just as normal.

Integration tests with Arquillian and Arquillian Spring Framework Extension

I would like to set up an infrastructure for integration testing.
Currently we bootstrap tomcat using maven and then execute httpunit tests.
But the current solution has few drawbacks.
Any changes committed to the database need to be rollback manually in the end if the test
Running code coverage on integration test is not straight forward (we are using sonar).
My goals are:
Allow automatic rollback between tests (hopefully using String #transaction and #rollback)
Simple straight forward code coverage
Using #RunWith that will bootstrap the system from JUnit and not externally
Interacting with live servlets and javascript (I consider switching from httpuinit to selenium…)
Reasonable execution time (at least not longer than the existing execution time)
The goals above look reasonable to me and common to many Java/J2ee projects.
I was thinking to achieve those goals by using Arquillian and Arquillian Spring Framework Extension component.
See also https://github.com/arquillian/arquillian-showcase/
Does anyone have and experience with Arquillian and with Arquillian Spring Framework Extension?
Can you share issues best practices and lesson learned?
Can anyone suggest an alternative approach to the above?
I can't fully answer your question. only some tips
Regarding the automatic rollback. In my case. Using liquibase to init the test data on "hsqldb" or "h2" which could be set as in-memory pattern. Then no need to roll back.
For Arquillian. It's a good real testing approach. What i learned is that "Arauillian Spring Framework Extension" is just a extension. You have to bind to a specific container like "jboss, glasshfish,tomcat" to make the test run.
But i don't know how to apply for a spring-based javaSE program which do not need application server support.
My lesson learned is the jboss port conflict. since jboss-dist is set 8080 as default http port. But our company proxy is same as 8080. So i can't use maven to get the jboss-dist artifact.
Hope others can give more info.

Using spring in a stand alone jar for dependency injectection

Am a total beginner with spring framework and trying to know if it even fits my use case, before investing time learning it.
I'm responsible for a stand alone java project(used as a jar by a server) which basically serves requests from a server, and in turn makes service calls to various internal services.
This standalone java project, currently has all of its service calls hard coded. I want to use Spring to inject dependencies so I can make this stuff testable.
I have no idea how spring works. Does it even hold for standalone jars or is it only for 'running applications'?
If I make my standalone project 'spring enabled', when the server uses my jar, will it automagically work by creating beans or is there some requirement from the server side?
In short, yes, you can use Spring in a standalone jar-application ("console application", if you will), we do it all the time at work. You just need to create the ApplicationContext yourself when your application starts, see for example here: http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application
This is just one example I pulled straight out of Google, there are probably numerous others. Still, you really need to read at least the basics from the Spring documentation to get started, otherwise you'll probably hit a wall pretty soon.

Resources