WireMock | Create your first Integration tests with WireMock and Kotlin
In this article I want to talk about mocking server responses with Wiremock. How would you test a function or a whole class, that uses a http request to get its data and processes it? You would need an actual test server with actual data on it to test it. This data should not be changed anymore, because tests would be depending on it. This would be a really bad solution, because you needed to configure a new dataset for every test and end up with a by itself useless server with even more useless data on it. What can you do about?
WireMock is the answer.
- What if you wanted to test different http requests with a different output?
- What if you want to test the same url but with a different output on every test?
- What if you want to specify the behaviour of a url when called globally for all tests?
WireMock is the answer to all those questions.
The code to test
This is the code to test.
- In this class we have two methods, the second one receives a Response from the Jenkins REST API that contains an HTML text and returns it. It uses khttp for the get request.
- The first method uses the parameters and double encodes the branch to branchName. This is used since in Jenkins the slashes need to be encoded.
- The method calls the receiveResponse() function.
- It returns the String after the Revision tag, which is a git hash, if the statusCode is exactly 200.
- If this is not the case it prints out a response and throws a custom exception.
The only way to test this whole class and not only a part of it is to use an Integration test with WireMock.
The Integration Test
- First of all, we need to create a new test class with the TestInstance annotation on it.
- Create the WireMock server with a dynamic port.
- Create an object of the Jenkins class
- Start the server and configure it for localhost and the port inside of the BeforeAll annotation.
- Create a stubFor the url you want to test the get request to. This url NEEDS to be without base URL (http://localhost).
- It will return a response with status 200
- With a body that contains an HTML text that contains in our case a git hash after the Revision clause.
- We call our method to test and save the result into the val hash.
- The last part is to assert that the hash is equal to a particular git hash.
In this test, we configured the WireMock server to respond only in a particular test itself. We could also put the stubFor into the BeforeAll annotation and reuse it in every test. This would be an example for this…
The possibilities are pretty much endless with this tool.
Would I do this the same way next time?
Yes, mostly. I would definitely choose the same mocking tool, but like in most cases, I would read the documentation of it a little bit more. It would have saved me some time trying to get it work.
What went good?
The creation of the WireMock server with a dynamic port worked better as expected. This was really easy and straight forward.
What needs improvement?
Next time i would read more in the documentation about my specific use-case. Most of the articles were about WireMock with Spring framework, which provides some extra annotations that I can’t use. I had a problem with the stubFor get() definition. I thought that i needed to use the whole link with the http://localhost before it, but I didn’t. I struggled a lot finding the error, but in the end this was shown in the documentation.
I hope this article was useful to you, thanks for reading 😊