Using LambdaClient.invoke in QuarkusTest how do I provide custom headers? - java

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.

Related

#SpringBootTest Toggable webEnvironment?

I want to toggle the webEnvironment config inside SpringBootTest to support running the tests in a pipeline (where the tests needs to be able to boot the server themselves) and locally (where I want to use a standalone server for faster tests.
Figured having a Profile which I could set would be a good solution to it but SpringBootTest seems to flat out ignore whatever profile I attach at the same level, is it simply too early in Spring's lifecycle for it to pick up profiles? Is there a better way to do this?
#Profile("myProfile")
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) // Starts regardless of what #Profile is
public class MyClass{
...
}
E: Related question:
SpringBootTest enable/disable webEnvironment based on input
E2: After some discussion down below I'm ditching the remote mode, not worth the hassle.
I was wondering why do you even need to rely on spring here? JUnit already has #EnabledIf annotation (documentation), so you can use it to not even attempt to run the test.
In my understanding it's even better, because this will work for all the tests that might even not run spring (unit tests for example). Also it should be better from the performance endpoint (you don't try to even run the Application Context, find/register beans, etc.)

Using Mockito for API Stubbing Load Test

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?

How to mock controllers / rest endpoints for unit testing in Play Framework 2.x [Java]

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.

How do I debug JmsTemplate?

I am using SpringsourceTool and the Spring framework.
I have some code that uses JmsTemplate to send messages via convertAndSend(Object). I want to debug it as a JUnit test. So, for the test class, I select Run->Debug As->JUnit Test.
I set a breakpoint and was able to closely follow the trace until I hit jmsTemplate.convertAndSend(obj) in which case when I hit Step Into (F5), I get a
Source not found.
Edit Source Lookup Path
Thanks!
Firstly, your problem is to with how to use Eclipse, and attaching sources to your library dependencies. This isn't a problem with JmsTemplate or Spring.
Having said that, you don't need to unit test JmsTemplate - it's already been unit tested by the Spring team. You can assume it works.
If your code is coupled to JmsTemplate, then consider refactoring it to depend on the JmsOperations interface instead. You can then mock or stub out that interface in your test.
If a deeper introspection into your JMS-communication is needed:
add logging.level.com.ibm.mq=TRACE to your application.properties
add -Dcom.ibm.msg.client.commonservices.trace.status=ON to your java-startup-parameters
Then check
your application-logfile
the application-start-directory, where you sould find a *.TRC-file with a lot of debug-information
see: https://www.ibm.com/docs/en/ibm-mq/9.0?topic=tmcja-collecting-mq-classes-jms-trace-by-using-java-system-property

Junit test case: Connection refused case

I am writing a Junit(4.x) test to test what happens when the web application is down.
When I hit the url in the browser, I get a message saying "Connection refused".
I am unsure about what to check for in the assert statements.
Do I check the header for this message? -- urlConnection.getResponseMessage() or
just say (expected = java.net.ConnectException) before the test case. I feel the latter is not specific enough.
EDIT: Right now, I'm using a combination of (expected = java.net.ConnectException) and assertEquals(502, urlConnection.getResponseCode). The test is passing.
Thanks,
Pratyusha.
First of all, your unit tests should not depend so much on external entities. What you describe is rather an integration test.
In a classic unit test, you could set up this scenario by using e.g. a mock HttpUrlConnection. This can be programmed to throw an exception from the desired method call. If you are not happy by simply acknowledging the type of exception thrown, you can always catch it within the test method, then assert the response message or whatever you are interested in.
However, from your post it is not clear to me what are you actually testing: a web client which depends on a server? A web app which calls another web app? Different tests may be adequate for different scenarios.
Integration tests in junit are fine. Many widely used open source projects use this approach. See CXF or Arquillian for examples of this approach.
For your question... you need to decide what the desired behaviour is and then test for this.
For example in this case you probably want to test the response code the server is returning. Or if "connection refused" really is desired behaviour then testing for (expected = java.net.ConnectException) should be sufficient.

Categories