Junit test case: Connection refused case - java

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.

Related

Invoking EJB method from JUnit - "No such EJB method"

I'm trying to call a method on a remote EJB in a JUnit test that will run SQL against a DB and return results. Here's the message from the exception:
java.lang.IllegalArgumentException: No such EJB method org.jboss.ejb.client.EJBMethodLocator#3c2f505 found on SiViewDBFacadeEAR-0.0.1-SNAPSHOT/SiViewDBFacadeEJB-0.0.1-SNAPSHOT/SiViewMMDBAccessBean
First of all, this error seems to be intermittent. I have a couple different methods in the EJB that run different SQL and return results as a HashMap. In my JUnit test I was calling these methods back to back and I was noticing that the call to the second method was always failing even if I switched the order of the calls. Just recently I tried calling the exact same method twice and it comes back the first time but fails the second time.
Does this problem signature ring a bell with anyone. I'm somewhat new to working with EJBs but this problem seems strange in its inconsistent nature.
Thanks all.
most common reason for this this error to occur is the EJB is not initialized or not deployed at all to the server that hosts it. Look at the logs on both client and server side to make sure all necessary components are initialized and running.

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

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.

How to purposely get a 409 HTTP Conflict response from a server?

We are implementing a retry mechanism (using Spring Retry) for http 409 Conflict responses, which we sometimes get on the production server.
But we wonder how to purposely get a server to respond with a 409 status code? In our cases, the error seems to happen whenever we try to load a lot of data in parallel; since the probability of it happening seems quite random, is there a method to get it consistently for testing purposes?
Well, There might be multiple possible ways to do so, You need to clarify where exactly you need 409 to be thrown ,
I assume (Its spring boot app) from one of your service (A) calls to another service/API(B) and you expect it to throw 409.
If that's the case, you can write #RunWith(SpringRunner.class)/#SpringBootTest test and mock the response from service/API B with 409 and test your retry mechanism.

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?

Arquillian and Selenium in mixed Container/Client mode

i am reading the tutorial on Arquillian's website
http://arquillian.org/guides/functional_testing_using_drone/
Under the paragraph of "Enabling Client Mode" they state that it is possible to mix in-container and client modes in the same test! Just leave off the testable attribute. Any method annotated with #RunAsClient will execute from the client, the remainder will execute inside the container, giving you the best of both worlds!
Here is my Issue.
I want to write a test that users
#Drone
DefaultSelenium browser and
#EJB
MyXXXRepository
I have one test that will add a user to the InMemory database before i have a Selenium test which logs in on the browser with that user...
So in order to get Selenium to work i need to tell the #Deployment to be testable=false, this will cause my #EJB to fail.
So according to the documentation i can skip the testable=false, if i tell the Selenium Test Method that it should run in Client Mode. According to the documentation this should work.
But!!!
This will throw an Exception
Caused by: java.lang.NoClassDefFoundError: Lcom/thoughtworks/selenium/DefaultSelenium;
So i need to be able to tell the
#Drone
DefaultSelenium browser;
To be in Client Mode as well...
Any takers?
Drone is intended to be client side. Personally I've never tried to deploy WebDriver/Drone tests and run it from the server. This sounds a bit crazy :) And obviously since the test itself is mixed classloader complains about the Drone-related imports.
But I have a solution for you which lets you test from the "grey-box" perspective. There is a fairly new extension in Arquillian universe called Warp which allows you to solve your very problem. Here's the guide.
Hope that helps.
I solved the problem by using an import script that will import the user prior to the test, this way i do not need to instantiate the repository and it is now a clean client side test.

Categories