I am currently experimenting with the support for WebSockets added in Spring 4.0, as described in this guide. As demonstrated in the guide, methods annotated with #MessageMapping can be added to any Spring MVC controller, which may also contain #RequestMapping methods.
The spring-test module has support for writing integration tests for #RequestMapping methods (as described here) in a very simple and fluid way:
#Test
public void getAccount() throws Exception {
this.mockMvc.perform(get("/accounts/1").accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}
Is there similar support for testing #MessageMapping methods using WebSockets? I have not found anything in any of the Spring modules, and none of the WebSocket guides contain any tests. If not, would I need to actually deploy the application and use a WebSocketConnectionManager to connect a test client? Or is there some API I can build on from spring-test?
This sample project contains such a small test client, but I would prefer to integrate this into the actual tests without requiring me to deploy the application and hardcode the deployed path in the tests.
There is nothing like Spring MVC Test for #MessageMapping methods yet. However, a similar approach to testing should be possible even without the fluent API. There is a ticket in JIRA (see https://jira.spring.io/browse/SPR-11266) to provide documentation so watch that ticket for more details in the very near future.
Related
There are several web spring boot java applications. I need to prepare several components for integration testing. My task is to mock all external behaviour such as other projects's components, db calls etc. I found a solution for this using #Profileannotation from spring framework. Here's an example. I can simply create new profile and declare two beans implementations for each profile: one for real usage, for production and another one for integration testing, for stubbing. It would look like this:
#Profile("PROD")
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
#Profile("MOCK")
#Configuration
#EnableWebSecurity
public class SecurityMockConfig extends WebSecurityConfigurerAdapter {
}
But I have doubts about this design. It looks little bit messy for me. Does this solution considered acceptable for task I have?
Doing this, your mocks and their configuration will be probably packaged with the app running in production.
This seems very odd to me. Would you package your units tests in your deliverd Spring application ? I don't think so. So I would like to say this is a "bad" design since testing dependencies should not be embedded with production code.
However, Spring's documentation about #Profile annotation is using the exemple of environment segregation.
Now, there is a question which needs to be answered: what do you mean by "integration testing" ?
Is this automated integration test ? Or do you want to run your application in different modes for the testing teams ?
Is this is an automated integration test, then there is no reason to use #Profile annotation as automated tests and production code will not be packaged together.
However, if you want your users to make integration tests, then you could create standalone fake project which will be used to simulate the external dependencies you are calling (database, webservices, etc).
Then, #Profile can be used to switch from fake to production mode but only through configuration file: fake profile will make call on your fake external services whereas production will call the real external services.
I have a Spring Boot application with a REST API. Behind the scenes it uses a vended SDK to call the vendors service. I need to run load tests on my application, but don’t want to call the vendor API and accidentally crash their system during testing.
Is it possible to use Mockito outside of a JUnit test to create a mock for the vendor SDK objects during the normal application runtime?
I figured I would use a profile based configuration beam to enable the mocked object when profile is “performance-test”. But I can find no article/discussion/mention of anyone using Mockito this way and it is making me second guess my approach. Thoughts?
You probably should look for using wiremock or similar software to mock the vendor service, like here: Integration Testing with a fake server
Wiremock is a stub server that you can conveniently start/stop from within JUnit tests. It acts like the remote server when you set up responses. The documentation is really good, I do not want to copy&paste all of it here.
Just a sample:
public class MyTest {
#Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort().dynamicHttpsPort());
#Test
public void exampleTest() {
stubFor(get(urlEqualTo("/my/resource"))
.willReturn(aResponse()
.withStatus(200)
.withBody("<response>Some content</response>")));
...
verify(postRequestedFor(urlMatching("/my/resource/[a-z0-9]+"))
.withRequestBody(matching(".*<message>1234</message>.*")));
}
}
For loadtest, you would rather run the stub standalone somewhere, and have some script set up the responses.
You probably don't find mention of Mockito because embedding mocks with stub responses into your application is a bad idea and will not help you getting realistic results for load tests (because your responses will be much faster and not pass through serialization/deserialization).
Else also look here:
How to mock remote REST API in unit test with Spring?
I have web application which uses technologies like spring , hibernate and Jersey Jax-rs rest for web sevices.
I can write the junit test cases for Dao layer as well as Service layer but i am not able to write junit test cases for jersey Rest which internally injects spring components.
Can anyone help ?
thanks.
You can use RestAssured for rest unit tests
You can find detail explanation in there
http://rest-assured.io
Sample Rest Unit Test from my own trial
#Test
public void createEntityShouldReturnCreated() throws Exception {
given().port(DemoApplicationTests.serverPort).contentType("application/json").body(detailDto).when()
.post("/api/employee").then().statusCode(201)
.header("X-demoApp-alert", "demoApp.entity.created");
}
I have a Spring service I want to test that uses the #Validated annotation on one of its method parameters. I would like to test it in the Spring container, but I am not sure if that is the best way. If testing in the container is the best solution for my situation, I would like to know how to run it in the container without loading my complete configuration. Any thoughts?
I ended up using the Spring Test Framework. I am using the standalone and the web application context of the mock MVC to test my annotations.
Spring 3.2.4 Test Framework
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html
Configuration Example
http://www.petrikainulainen.net/programming/spring-framework/unit-testing-of-spring-mvc-controllers-configuration/
How can I call a spring annotated controller from a JUnit test, in a way so that spring comes into play with binding and all, but without making a http request (just mocking out the request object)? It has to include the whole shebang from the controller and down, with JPA and database and all. We are also using EJB, so maybe a bean can do this for me?
The reason for this, is that I would like to have some automatic tests that tests performance of specific controller calls, but without the client and network traffic.
Thank you
There's a section in the Spring reference about Unit-testing Spring MVC.
Here's the relevant excerpt:
Unit testing Spring MVC Controllers
To test your Spring MVC Controllers, use
ModelAndViewAssert combined with
MockHttpServletRequest,
MockHttpSession, and so on from the
org.springframework.mock.web package.
Reference:
org.springframework.mock.web
package summary
ModelAndViewAssert javadoc
You can specify a test-specific spring context for your unit test like this:
#ContextConfiguration(locations = "classpath:spring/ITestAssembly.xml")
You can then make this context use a mock or embedded data source instead of the real database.