WebServices, what to unit test? - spring

I am developing a web application using Spring + Hibernate, plus CXF to convert my Service layer into a WebServices endpoint. I want to unit test my code, and when it comes to the DAOs I have no trouble: I create an in-memory database filled with my test data, then test DAOs against that.
But when testing the Service layer, most of my methods are like these:
#Override
#Transactional
public void saveProgramacion(ProgramacionDTO programacion) {
programacionDAO.persist(this.map(programacion, Programacion.class));
}
That is, my method just maps the VO to a DTO (using an external mapper) then calls a method of my DAO. Just that.
I used mockito to mock my DAO but honestly there are no instructions to provide mockito with since the service method itself does very little and does not check the DAO result. Given the fact that the mapper is an external dependency and thus would require its own unit test, what should I be testing here? What would be a proper unit test in this case?

Related

What does Mocking a repository mean in mockito?

I am mocking a repository with the annotation #mock and then saving some data to the repository in the test class. Is the data really getting stored in the repository?
In another class when the same data is fetched it is showing not found. How will I test my class if the data is not stored in the repository?
Most likely, when you use the #Mock annotation correctly in your test code, your mocking framework will come and instantiate something for you under that name:
#Mock
WhatEver someWhatEver;
In other words: when the above "executes", someWhatEver will reference some object that conforms to the "API" that the WhatEver class provides.
Meaning: you can call all methods that exist on that class. And nothing will happen. Because someWhatEver isn't a instance of your real production class. It is something that looks like it.
Thus, the real answer is: you step back, and you research the whole topic. There is no point in doing "unit testing" using some mocking framework without "understanding" what you are doing. The tutorial by vogella is a good starting point.
Mocking is a way to encapsulate your unit tests. If you want to test a service method you are not interested if the repository is working. For this you will write repository tests. Therefore you mock the repository call and tell which result should be returned to test your method in all possible situation. The mock itself is a proxy, therefore there the data which are you saved are not really safed in your database. This has the advantage that you havenĀ“t to start your whole context and the tests are much faster.
When we want to do a Service Unit Test in SpringBoot Application We have not gone use Real DataBase just we need to Mock DataBases.
Similarly When u want to do Unit Test any External Serivce in Your class Just U can Mock that External Service call.
A Mockito mock allows us to stub a method call. That means we can stub a method to return a specific object. For example, we can mock a Spring Data JPA repository in a service class to stub a getBooks() method of the repository to return a Book object.

How to set response date format in rest assured mock mvc while testing spring could contract for a web service?

I am using tests generated by spring cloud contracts to test web service response.
The service used to return date as timestamp, now with the updated Spring version (2.0.5) dates are returned in the "2018-11-30T21:16:18.220+0000" format. The contract tests are still passing without any change. I learned that this is because Spring could contract uses RestAssuredMockMvc which is unaware of springs application configs. How can I change the config in the contracts to make sure that contracts always check for the date in same format as that are correctly returned by the service?
For Spring Boot application, simple way to execute RestAssured against spring application setup is:
#RunWith(SpringRunner.class)
#WebMvcTest
// or #SpringBootTest
public abstract class BaseContractTest {
#Autowired
protected MockMvc mockMvc;
#Before
public void setup() {
RestAssuredMockMvc.mockMvc(mockMvc);
}
}
Version with #WebTestClient runs faster but needs mocking services, version with #SpringBootTest runs slower but utilize whole application.
Proposed in previous answer RestAssuredMockMvc.webAppContextSetup() is very similar to version with #SpringBootTest. The second proposition, RestAssuredMockMvc.standaloneSetup(), requires a complicated configuration, different than Spring application configuration.
For that reason RestAssuredMockMvc.standaloneSetup() is error prone and worse than #WebMvcTest.
RestAssuredMockMvc.webAppContextSetup() is OK
Try this.
Setup object mapper with RestAssuredMockMvc.standaloneSetup
RestAssuredMockMvc.standaloneSetup(
MockMvcBuilders
.standaloneSetup(yourcontroller).setMessageConverters(mappingJackson2HttpMessageConverter)
);
Either add the missing configuration to the mockmvc rest assured setup or use explicit mode of tests generation and setup a real spring boot context

No Mocking on MongoRepository

I have the following configuration
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootApplication(scanBasePackageClasses= {})
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes= {})
#ActiveProfiles("local")
I want to run a JUnit test without mocking the MongoRepository calls but it automatically mocks the MongoRepo calls and gives back null. Is their a way around it?
Firstly, you should decide what kind of test you want to perform,
Unit test
or
Integration test
If you are doing unit test , you should write separate test cases for each layer
Controller layer - use mockmvc and mock service layer calls
Service layer - Here you have two options, YOu can mock repository calls or you can use some in memory database(like Fongo) and put some data before testing and test it.
If you want to test all layers together and with real database then you should write Integration tests.

Spring boot: should validation been tested when testing controller layer

I am working on the project where I want to have decent test-infrastructure.
I am using spring boot, which makes easier for testing separate layers of the project: for example
If I want to test controller layer I will mock (with mockito) service dependencies of the controller, and check whether right service method will be called on given http request, and expected http status will be returned. If I want to test service layer I will mock repository and business logic dependencies. And so on.
In my project, I am using spring validators to check whether request body is passed correctly (with the use of #InitBinder method I am adding my custom validators to the WebDataBinder, and with use of #Valid annotation, those validators are called on the parsed request body).
So my question is: is it good practice to mock validators and test only controller logic (validators will be tested in context of validator layer)?
I am just not sure which is the best practice, and is it normal to test validators along with controllers?
Mocking is not always best option, when you are testing your controller logic, validation logic and especially business logic. I would not recommend to mock any of these.
You can use various framework to test:
Controller logic - RestAssured or MockMvc
Business logic - Plain JUnit tests under SpringBootTest and SpringRunner
Validation logic - Plain JUnit tests under SpringBootTest and
SpringRunner
For further reading:
RestAssured: http://rest-assured.io/
Spring validator test: Writing JUnit tests for Spring Validator implementation

Testing Spring Webflow Action Classes

I am writing test case for my webflow using org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests
public class MyFlowExecutionTests extends AbstractXmlFlowExecutionTests {
}
In some cases my logic is simple, So I invoke my service layer directly from the Spring webflow.
In some cases I use an extenstion of org.springframework.webflow.action.MultiAction classes and I invoke my service layer from the action classes.
In the first scenario, wrting test case is straight forward. In the second scenario, I found it really complex to write the test cases using org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests for the Action class.
In the first scenario, I can mock all the service classes used from my flow. In the second scenario, using easy mock class extension, I can mock the action class. But then I need to mock the service layers used inside, which I think mock can't handle that well.
I am now thinking of somehow moving the Action class code to Spring EL. Or Anybody have a better idea for testing the action class code along with webflow code?

Resources