Spring boot autowire and cross feature shared data - spring

As per the serenity BDD each scenario is solid
Serenity session variable will be lost for the second scenario
I am integrating SpringBoot using #SpringBootTest
My code is perfectly working whatever I wrote in the Background section of the feature file to call an URL, I wrote a piece of code to not to call the same service URL for the second time, rather it will take the data which is stored in a HashMap from an object which autowired using #Autowired
My Question is, is this against the BDD that one data gets maintained across more than one feature file or scenario

Session data is reset for each scenario (by intent - scenarios are meant to be independent of each other). If you need to share data across multiple scenarios, you will need to implement this yourself.

Related

What is correct way writing Integration test in Spring or Spring Boot based application

I am writing code for Spring Boot Rest application which interact with DB using Spring JPA.
My app have 3 main layers Controller,Service,Repository and it have CURD operations.
I want to follow TDD approach. My question is how do I populate data for each VERB implementation.
For example I am starting with CREATE impl and implemented CREATE flow with Controller,Service,Repo etc. Now to implement PUT,GET,DELETE I need to populate data while writing my tests. For this purpose I used Injecting Repository in my Integration test class and loaded data before my actual Test Runs or Used DataLoader with CommandLineRunner Implemention to pre-populate the data. Buy my collegue insisted me I should never use Repository in Integration Test class for populating data instead should User Service class bean and call CREATE implementation for required data population.
Is it any best practice or guideline documentation to design Integration Test and Unit Test?
And main question did we use Repository in Integration Test class for populating data or not?
The main motive of writing integration testing is to test the interface between two software units or modules. It focuses on determining the correctness of the interface. That means you should test your application in the sense of whether your app can be integrated into other software or not. In that case, your beans like repositories or services are not injectable or applicable from the other software except your endpoints that you are exposing through controllers.
Writing Integration Test
There are a couple of things you should consider before writing your integration test such as the scope of your test cases, scenarios of each endpoint, tools/libraries to write the tests, etc.
You can use something like RestTemplate or MockMvc to invoke HTTP requests(POST, PUT, CREATE, DELETE). For example, make a GET request with RestTemplate,
#Autowired
private RestTemplate restTemplate;
#Test
void givenYourObjectTypes_whenGetYourObjectTypes_thenStatus200()
ResponseEntity<YourObjectType> response = restTemplate.getForEntity(requestUrl, YourObjectType.class);
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
}
My question is how do I populate data for each VERB implementation.
There are annotations called BeforeEach and BeforeAll, you can use either of them in a setup method to populate your data
Is it any best practice or guideline documentation to design Integration Test and Unit Test?
There are a lot of documentations you can find out in google. But once you grasp the core concept of the test, you will be intimated to workaround. Still, I would refer to you to have a look at an article by Martin Fowler on Integration Test (It's my personal preference).
And the main question did we use Repository in Integration Test class for populating data or not?
Populating data using repositories is not the recommended approach. Instead, I suggest you use CREATE API to populate data which would be a real scenario while integrating with other services/UI/modules/software.
Moreover, You could try H2 dependency with scope test while testing your application which makes it faster to perform the test cases. But note that it is only applicable if you are using SQL database.

Spring design pattern for common update service or module

I have a use case where I would like build a common interface or service which can update entities of application. Example case is shown as below:
Now every application has to handle update functionality of entities. Rather than implementing update functionality in n application module. I would like to build a common interface or server in spring boot.
Service will be like below:
My question is how to design service/interface which can used for above scenario. Any api or tool which can help me to achieve this. I dont want to write code for update in every application module.
Thanks in advance.
Last year I was thinking about the similar concept to yours, but in Apache Camel framework context. I haven't got enough time and motivation to do so, but your post encouraged me to give it a try - perhaps mostly because I've found your concept very similar to mine.
This is how I see it:
So basically I considered an environment with application that might uses N modules/plugins that enriches application's features, i.e. processing feature etc. Application uses module/plugin when it is available in the classpath - considering Java background. When the module is not available application works without its functionality like it was never there. Moreover I wanted to implement it purely using framework capabilities - in this case Spring - without ugly hacks/ifs in the source code.
Three solutions come to my mind:
- using request/response interceptors and modifying(#ControllerAdvice)
- using Spring AOP to intercept method invocations in *Service proxy classes
- using Apache Camel framework to create a routes for processing entities
Here's the brief overview of POC that I implemented:
I've chosen Spring AOP because I've never been using it before on my own.
simple EmployeeService that simulates saving employee - EmployeeEntity
3 processors that simulates Processing Modules that could be located outside the application. These three modules change properties of EmployeeEntity in some way.
one Aspect that intercepts "save" method in EmployeeService and handles invocation of available processors
In the next steps I'd like to externalize these Processors so these are some kind of pluggable jar files.
I'm wondering if this is something that you wanted to achieve?
link to Spring AOP introduction here: https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/core.html#aop
link to repository of mentioned POC: https://github.com/bkpawlowski/spring-aop

Transaction Management while performing Functional Testing Spring Rest Interface

I am trying to write a Functional Testing suite. The test utilizes a bunch of Rest calls to execute workflows (The testing is black-box testing, using the rest interface.). The application under rest is Spring 3 and uses Spring's transaction management(DataSourceTransactionManager). To avoid individual setup and tear-down methods, I was thinking of making the transaction rollback-able.This is accomplished by using #TransactionConfiguration(defaultRollback = true) when doing unit\integration testing, but I am not aware of a straight forward way of doing it, while performing integration testing(since they are individual rest calls).
The application under test is not single threaded and multiple concurrent testing suite might be running at the same time on the same database instance\application.
My preliminary analysis leads me to believe that I should force spring to use the same rollback-able transaction for all the methods in a test suite.(Like using a Factory method that returns a Transaction based on a unique identifier. Passing a unique request parameter and using AOP to somehow inject a transaction for this thread)
Have any of you done anything similar. I would really appreciate some ideas.
Thank you.
Good Question,
I am planning to use transaction in my Junit test too
Please use if the following works for you
#Test
#Transactional
#Rollback(true)
It will take some time for me to implement this in my project but hope, this will help you before I need this.
One more thing which i read is the program is multithreaded.
Do you not wish to use the Isolation level which are provided by spring ? But I think it will be developers who should take care of this.

Good strategy for Spring Framework end-to-end testing

So this is a rather "big" question, but what I'm trying to accomplish is the following:
I have a Spring application, MVC, JDBC (MySQL) and JSP running on tomcat.
My objective is to test the entire "stack" using a proper method.
What I have so far is Junit using Selenium to simulate an actual user interacting with the application (requires a dummy account for that), and performing different validations such as, see if element is present in the page, see if the database has a specific value or if a value matches the database.
1st concern is that this is actually using the database so it's hard to test certain scenarios. I would really like to be able to mock the database. Have it emulate specific account configs, data states etc
2nd concern is that given the fact that I use what is in the database, and data is continuously changing, it is hard to predict behavior, and therefore properly asserting
I looked at Spring Test but it allows for testing outside a servlet container, so no JSP and no Javascript testing possible.
I saw DBUtils documentation but not sure if it will help me in this case
So, to my fellow developers, I would like to ask for tips to:
Run selenium tests on top of a mocked database
Allow different configs per test
Keep compatibility with Maven/Gradle
I have started with an ordered autowire feature to support this kind of stubbing.
It's basically an idea that i took over from the Seam framework i was working with in the past but i couldnt find yet a similar thing in spring.
The idea is to have a precedence annotation (fw, app,mock,...) that will be used to resolve the current implementation of an autowired bean. This is easy already in xml but not with java config.
So we have our normal repository beans in with app precedence and a test package stubbing these classes with mock precedence.
If both are in the classpath spring would normally fail with a duplicate bean found exception. In our case the extended beanfactory simply takes the bean with the highest precedence.
Im not sure if the order annotation of spring could be used directly but i prefered to have "well defined" precedence scopes anyway, so it will be clear for our developers what this is about.
! While this is a nice approach to stub so beans for testing i would not use it to replace a database definition but rather go with an inmemory database like hsql, like some previous answers mentionned already. !

Test Driven Development For Complex Methods involving external dependency

I am implementing a Service Contract for WCF Service.
As per TDD I wrote a test case to just pass it using hardcoded values.
After that I started to put real logic into my Service implementation. The actual logic relies on 3-4 external service and database.
What should I do to my original test case that I wrote ?
If i Keep it same in order to make test pass it will have to call several other external services.
So I have question in general what should I do if I write a test case for a Business Facade first using TDD and later when I add real logic, if it involves external dependency.
Utilize a mocking framework (with dependency inversion or just a factory) so you can inject fake dependencies into the object. These can then then just return canned responses and/or be checked that the class utilizes the dependencies how you intended.
As an example, if your code calls a repository to save, we don't really care in the business method test that the repository did actually save to a persistance store, only that it got called and returned some data if required. What you're really testing is how your code reacts to what the dependency returned, or if it was utilzed correctly - but not the dependency's actual functionality
Ideally the first test should have been representative of how the class/method will work and return data, so the test would still be valid once you're finished.

Resources