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?
Related
I'm trying to integrate Datadog into a Quarkus lambda function. The unit test is failing with a NullPointerException because Datadog can't get the function ARN from the context. It looks like there is a need to supply this header Lambda-Runtime-Invoked-Function-Arn in the HTTP request.
Is there anyway to customize the request headers using QuarkusTest? We are using LambdaClient.invoke.
Generally tests should be as close to the production run as possible, so altering headers does not seem to be the right path.
Is the unit test focused on the datadog part of the code?
If not:
If datadog just broke the existing unit tests, you have multiple options to fix it:
With #QuarkusTest you could just Mock the datadog related parts and register that instead of the original using #InjectMock.
I also found that using #QuarkusTest for unit testing can be a bit tricky in some cases and using plain Junit5 with Mockito can be a bit simpler with less unpredictable 'magic'.
If yes:
Since most things involving datadog is about sending data to an external service this might be more suitable for the scope of an integration test instead of a unit test. In that case you would need a test environment, or maybe reconsider if you really need to test external data collection at all.
We are developing a project with Java on Play Framework 2.x and have some rest endpoints. Also we have some test cases for them like as follows:
#Test
public void testLogout() throws Exception {
FakeRequest request = new FakeRequest("GET", "/product/api/v1/logout");
Result result = route(request);
assertThat(status(result)).isEqualTo(OK);
assertThat(contentType(result)).isEqualTo("application/json");
assertThat(contentAsString(result)).contains("result");
}
On the other hand, we have some methods [like register()] which can not test in production database.
What is the correct way to test the methods which affect the prod database? I think mocking but I am not sure that and I don't know how to do. If mocking is a good choice, is there any working example?
Please give me some advice about this issue.
I think the correct way is not to test against production database.
I divide the tests in 2 groups, unit tests and integration tests. Unit tests are commonly known, and in integration tests I test everything that is outside the application itself (for example, the database) and the conections between them.
I run the unit tests using a mock in memory database when needed and integration tests against a database with same structure as the production one but not the same database.
I hope my approach will help you.
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.
I am in a process of writing web application that uses Play framework (2.1.1 version).
I wrote my first, very simple, controller and I wanted to unit test it.
The thing is, because Play controllers are all static I am wondering what is the correct way to mock out dependencies, for example, lets take some MyService:
private static MyService myService = new MyServiceImpl();
I am using this kind of initialization in my application to deliver controller dependencies.
Now, if I would want to mock out my dependency I could create static method that sets the myService field to mocked out implementation of MyService.
Is this the way it is done in play framework application that is written in Java? Or maybe there is some more "idiomatic" way to do this kind of thing in Play framework.
How to achieve something like that is documented on http://www.playframework.com/documentation/2.1.1/JavaInjection .
On https://github.com/guillaumebort/play20-spring-demo is a demo of a Play Spring project.
With play.Play.isTest() you can check if you are in test mode. It is documented on http://www.playframework.com/documentation/api/2.1.1/java/play/Play.html .
I have written a java client server application (not http), which i need to load test. However, most tools out there such as jmeter and grinder seem to be targeted to http requests. Any suggestions?
Thanks!
JMeter allows writing pluginns. If your application uses protocol other than HTTP it seems that the protocol is proprietary, so writing tests requires some custom implementation anyway. JMeter allows this and it is highly recommended.
since we have no idea what protocol you're using, write your own client in a way easily extendable for load testing.
You could have a look at Soatest which claims to be socket based and should be able to use whichever web protocol you are using (hopefully TCP/UDP).
You can use the JUnit4 or JUnit5 based load runners below which can simply accept your Unit tests and generate load on the target server. These need not be HTTP tests, these could be any tests annotated with #Test
JUnit4 based load runner
JUnit5 based load runner
The load configs look like below to ramp up or ramp down your load:
number.of.threads=2
ramp.up.period.in.seconds=10
loop.count=1
Your load test will look like below:
#LoadWith("our_load_config.properties")
#TestMapping(testClass = AnyTestEndPoint.class, testMethod = "anyTestMethod")
#RunWith(ZeroCodeLoadRunner.class)
public class LoadTest {
}
Your JUnit test which is fed to the load generator,
The test class looks like below:
import org.junit.Test;
public class AnyTestEndPoint {
#Test
public void anyTestMethod() throws Exception {
...
// You can have your client code invoking the target server
...
}
}
Note:
You can feed multiple Junit tests too to the load reactor, to generate load on different part of the server logic/apis/processes.
Visit the HelloWorld Examples for more details.