I'm trying to perform a POST request on URL outside the current context, and it looks like Spring cannot understand it.
Test code:
String content = mvc
.perform(post("http://some-external-url.com:8080/somepath)
.header("Authorization", authorization)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("username", username)
.param("password", password)
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
Works like a charm on current context. But remote service cannot be reached at all. It seems like "http://some-external-url.com:8080" part is ignored.
Mock creation code:
mvc = MockMvcBuilders.webAppContextSetup(context).build();
Is there any way to make it work? Because using standard Java HttpUrlConnection class is a huge pain.
No. There is no way to make the Spring MVC Test Framework work with external servers (or any actual server for that matter).
As stated in the Spring Reference Manual,
The Spring MVC Test framework provides first class support for testing
Spring MVC code using a fluent API that can be used with JUnit,
TestNG, or any other testing framework. It’s built on the Servlet API
mock objects from the spring-test module and hence does not use a
running Servlet container.
The last sentence spells it out: Spring MVC Test does not use a running Servlet container. In fact, it cannot be used with a running Servlet container or any kind of actual server (local or remote).
As an alternative, if you must test against an external server, you could then consider using REST Assured instead of Spring MVC Test for those special cases.
You can use new RestTemplate().getForObject("http://some-external-url.com:8080/somepath", String.class)
Related
I want to create a REST API in spring boot which can handle around 100TPS. Lets say I create a basic REST api using a sample application in spring boot. Does this automatically handles multi threading. Lets consider the code bellow.
#RequestMapping(method = RequestMethod.POST, value="findByPackageActivationId")
#ResponseBody
public JSONObject findByPackageActivationId(#RequestBody IncomingRestObject incomingRestObject) {
//My work here
}
By default Spring Boot web applications are multi-threaded and will handle multiple requests concurrently.REST controller is multithreaded as the DisptcherServlet handles multiple requests from the clients concurrently and serves using the respective controller methods.You can change any of the default thread settings as well (e.g. server.tomcat.max-threads). For more information refer here :-
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc
REST controller is multithreaded as the DisptcherServlet handles multiple requests from the clients concurrently and serves using the respective controller method
You can scale your app as per your requirements to achive desired TPS
https://dzone.com/articles/how-to-test-if-your-multi-threaded-java-rest-servi
For every request from the client, the server will create a new thread and assign that request to newly created thread. You don't have to handle this explicitly.
Also for your requirement(100 Threads), you can configure this on the server. You can refer this link for tomcat configuration as its default server for spri.
Spring Framework provide these feature internally, these are benefits that spring provide over core servlet coding that we used to do in older days. It also provide the way to control it.
For Ex you can change limit of number of thread to create using server.tomcat.max-threads (For tomcat).
For Basic understading on multi threading with spring boot please refer https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/
For all I know, MockMvc is just testing the Controller, and mocking the Service layer.
Whilst RestAssured and TestRestTemplate are testing the running instance of our API.
Is that correct?
And what's the difference between RestAssured and Spring Boot's TestRestTemplate?
MockMvc is one of the classes in spring-test. This is primarily used for unit testing of the controller layer. Not just your controller class. This is for tetsing the controller layer. But you have to mock service and other layers. Hence it is primarily used for unit testing.
TestRestTemplate is again part of spring test, as the documentation says,
Convenient alternative of {#link RestTemplate} that is suitable for
integration tests.
This can be used to test your Rest Service/ endpoints. One of the main difference is you use MockMvc for unit testing and TestRestTemplate for Integration testing. In other words, for using MockMvc, you don't need a running instance of server, but for TestRestTemplate you would need.
RestAssured is a completely different framework. This has nothing to do with Spring. This is a librariy, which provides various ways to test any REST service with fluent BDD style interface.
As mentioned MockMvc is used to mock the service layer. It is useful in unit-testing of the code.
Whereas both RestAssured and TestRestTemplate are used for integration-testing which is end to end APIs testing.
Also, there is not much difference between RestAssured and Spring Boot's TestRestTemplate. You can use RestAssured for Spring-Boot Application or can go ahead with TestRestTemplate which is a Spring library.
MockMvc is primarily used for web layer testing. Web layer testing is essentially writing fine-grained tests specifically designed to test your app’s controllers. It is very similar to writing regular unit tests for classes where you need mock dependencies for testing specific methods.
As far as comparing RestAssured vs TestRestTemplate they do pretty much the same thing. When it comes to RESTful based API integration testing and validation, TestRestTemplate and RestAssured both offer convenient methods to create and execute your HTTP calls with custom headers, auth, content types, query parameters, payload content, cookies, etc. The main difference -aside from syntax- is that TestRestTemplate is part of Spring’s test framework which comes bundled with the spring-boot-starter-test dependency.
Check out this article - Testing Spring Boot RESTful APIs using MockMvc/Mockito, Test RestTemplate and RestAssured - it has additional explanation and robust examples on the usage for all three (MockMvc, TestRestTemplate, and RestAssured).
What's the best way to make a REST call?
Should I use Apache Http Client or Should I use Spring Rest Template.
On what basis I can decide which one I should go for?
I need to make a call to this url-
http://localhost:8080/service/Service/v1/get/USERID=10000/profile.ACCOUNT.SERVICE"
And after getting the response back, I just need to see whether that response contains any particular string or not.
Spring RestTemplate follows the pattern for all the *Template classes within the core Spring framework and the various sub-frameworks: JdbcTemplate, HibernateTemplate, WebServiceTemplate etc etc.
The idea of all of these Template classes is to reduce the boilerplate code (exception handling, repetitive stuff and concentrate on your business logic). I would definitely use it over the simple HttpClient.
To get the class you'll need the spring-web dependency.
We have Spring MVC application. One module requires to call the Spring Controller from standalone java app.
Can I do that?
Dead easy:
new java.net.URL("http://localhost:8080/path/to/your/controller").openStream();
Just like you would do it in the browser. If you want to call the Java code directly, do not publish your controllers. Instead, extract business logic and provide it as a library.
Yes.
It's a POJO, especially if you use Spring 3.x. The newest versions don't even extend an interface or base class.
I'd call it through its http interface as it's a Spring controller. You could use a clientside http request and use the response. I'm guessing the method you wish to call does not resolve to a view, if that's the case then just use something like the RestTemplate class that comes with Spring 3.
Not sure if it would be a good idea to call it directly as Spring MVC projects are usually hidden away inside servlet wars.
I have a JAX-RS web service implemented with Jersey library and now I want to test it. In order to do that I'd like to host this service in my test by preinitializing it with mocked services.
What is the best way to host such a service and execute the test calls?
#Path("/srv")
public class MyService
{
#GET
public void action(#Context UriInfo uri)
{ ... }
}
#Test
public void myTest()
{
MyService service = new MyService();
service.setSomething(...);
// How do I host it?
// How do I call it?
}
The new (revised) Jersey Test Framework which is part of the Jersey 1.1.2-ea release now supports the In-Process or In-Memory testing. In order to run your tests in-memory all you have to do is set the property test.containerFactory to com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory, i.e., run your tests as follows:
mvn clean test -Dtest.containerFactory=com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory -DenableLogging
For more details please go through the blog entry titled Jersey Test Framework re-visited! at http://blogs.oracle.com/naresh.
I believe the Jersey Test Framework provides a solution for your requirement. It allows you to deploy a single service, and run all its tests. You could use the framework to run your tests against Grizzly Web Container, Embedded GlassFish and/or HTTPServer.
Please note that you could use the framework to run your tests against the regular web containers like GlassFish and Tomcat too. In case you have any more queries please feel free to send me or the Jersey users mailing list - users#jersey.dev.java.net an e-mail.
I haven't tried it, but a JUnit extension like HtmlUnit or HttpUnit may be a good way to test a JAX-RS/Jersey service. The test case can use XPaths to find expected return values and validate the returned value against the expected. See: http://htmlunit.sourceforge.net/gettingStarted.html for more info.
You can use Grizzly to host the services and then use the Jersey Client to access them. Take a look at the sample applications. For example, in the Bookstore sample you may find the TestSupport class and JerseyTest class (found in the jersey-test-framework) of particular interest.
I hope this helps.
(Unfortunately Stack Overflow wouldn't let me post until I removed all the hyperlinks so happy Googling!).
Okay I get it now. Right now the framework doesn't support IN PROCESS, bt we are working on it.
We will see that this support would be added in a coming version of the Jersey Test Framework
Have you looked in to using the Jersey Test Framework? Unfortunately it's still more integration test than unit test, but it might get you on your way.